import XCTest
@testable import Rosetta

@MainActor
final class CallRoutingTests: XCTestCase {
    private let ownKey = "02-own"
    private let peerA = "02-peer-a"
    private let peerB = "02-peer-b"

    override func setUp() {
        super.setUp()
        CallManager.shared.resetForSessionEnd()
        CallManager.shared.bindAccount(publicKey: ownKey)
    }

    override func tearDown() {
        CallManager.shared.resetForSessionEnd()
        super.tearDown()
    }

    func testIncomingCallMovesToIncomingPhase() {
        let packet = PacketSignalPeer(
            src: peerA,
            dst: ownKey,
            sharedPublic: "",
            signalType: .call,
            roomId: ""
        )

        CallManager.shared.testHandleSignalPacket(packet)

        XCTAssertEqual(CallManager.shared.uiState.phase, .incoming)
        XCTAssertEqual(CallManager.shared.uiState.peerPublicKey, peerA)
    }

    func testBusySignalEndsCurrentCallStateWithoutCrosstalk() {
        CallManager.shared.testSetUiState(
            CallUiState(
                phase: .outgoing,
                peerPublicKey: peerA,
                statusText: "Calling..."
            )
        )

        let packet = PacketSignalPeer(
            src: "",
            dst: "",
            sharedPublic: "",
            signalType: .endCallBecauseBusy,
            roomId: ""
        )
        CallManager.shared.testHandleSignalPacket(packet)

        XCTAssertEqual(CallManager.shared.uiState.phase, .idle)
        XCTAssertEqual(CallManager.shared.uiState.statusText, "User is busy")
        XCTAssertEqual(CallManager.shared.uiState.peerPublicKey, "")
    }

    func testPeerDisconnectedSignalEndsCurrentCallState() {
        CallManager.shared.testSetUiState(
            CallUiState(
                phase: .active,
                peerPublicKey: peerA,
                statusText: "Call active"
            )
        )

        let packet = PacketSignalPeer(
            src: "",
            dst: "",
            sharedPublic: "",
            signalType: .endCallBecausePeerDisconnected,
            roomId: ""
        )
        CallManager.shared.testHandleSignalPacket(packet)

        XCTAssertEqual(CallManager.shared.uiState.phase, .idle)
        XCTAssertEqual(CallManager.shared.uiState.statusText, "Peer disconnected")
        XCTAssertEqual(CallManager.shared.uiState.peerPublicKey, "")
    }

    func testInterleavingForeignSignalDoesNotOverrideActivePeer() {
        CallManager.shared.testSetUiState(
            CallUiState(
                phase: .outgoing,
                peerPublicKey: peerA,
                statusText: "Calling..."
            )
        )

        let foreignPacket = PacketSignalPeer(
            src: peerB,
            dst: ownKey,
            sharedPublic: "",
            signalType: .call,
            roomId: ""
        )
        CallManager.shared.testHandleSignalPacket(foreignPacket)

        XCTAssertEqual(CallManager.shared.uiState.phase, .outgoing)
        XCTAssertEqual(CallManager.shared.uiState.peerPublicKey, peerA)
        XCTAssertEqual(CallManager.shared.uiState.statusText, "Calling...")
    }
}
