import XCTest
@testable import lichunWebsocket

final class EventV2ResponseTests: XCTestCase {
    var webSocketService: EventV2ResponseCapturingWebSocketService!

    override func setUpWithError() throws {
        try super.setUpWithError()
        continueAfterFailure = false

        let config = URLSessionConfiguration.ephemeral
        config.protocolClasses = [EventV2ResponseMockURLProtocol.self]
        let session = URLSession(configuration: config)
        let delegateQueue = OperationQueue()
        webSocketService = EventV2ResponseCapturingWebSocketService(urlSession: session, delegateQueue: delegateQueue)
    }

    override func tearDownWithError() throws {
        webSocketService.disconnect()
        webSocketService = nil
        super.tearDown()
    }

    func testSendAnswerUsesEventResponsePayloadShape() throws {
        let answer = AnswerOption(
            option: "Help",
            id: "help",
            data: nil,
            energyCost: 2,
            moneyCost: nil,
            diamondCost: nil
        )

        webSocketService.sendAnswer(answer: answer, questionID: "event_adult")

        let sentMessage = try XCTUnwrap(webSocketService.sentMessages.last)
        XCTAssertEqual(sentMessage["type"] as? String, "eventResponse")

        let body = try XCTUnwrap(sentMessage["message"] as? [String: Any])
        XCTAssertEqual(body["eventId"] as? String, "event_adult")
        XCTAssertEqual(body["choiceId"] as? String, "help")
    }

    func testRemoveQuestionRemovesByEventId() throws {
        let firstQuestion = Question(
            id: "event_1",
            question: "First?",
            answers: [AnswerOption(option: "A", id: "a", data: nil, energyCost: nil, moneyCost: nil, diamondCost: nil)],
            characters: nil,
            image: nil
        )
        let secondQuestion = Question(
            id: "event_2",
            question: "Second?",
            answers: [AnswerOption(option: "B", id: "b", data: nil, energyCost: nil, moneyCost: nil, diamondCost: nil)],
            characters: nil,
            image: nil
        )

        webSocketService.questionQueue = [firstQuestion, secondQuestion]
        webSocketService.currentQuestion = firstQuestion

        webSocketService.removeQuestion(eventId: "event_1")

        XCTAssertEqual(webSocketService.questionQueue.map(\.eventId), ["event_2"])
        XCTAssertEqual(webSocketService.currentQuestion?.eventId, "event_2")
    }
}

final class EventV2ResponseCapturingWebSocketService: WebSocketService {
    var sentMessages: [[String: Any]] = []

    override func sendMessage(message: [String : Any]) {
        sentMessages.append(message)
    }
}

private final class EventV2ResponseMockURLProtocol: URLProtocol {
    override class func canInit(with request: URLRequest) -> Bool {
        true
    }

    override class func canonicalRequest(for request: URLRequest) -> URLRequest {
        request
    }

    override func startLoading() {}
    override func stopLoading() {}
}
