//
//  MockWebSocketService.swift
//  lichunWebsocketTests
//
//  Mock WebSocket service for testing without network
//

import Foundation
import Combine
@testable import lichunWebsocket

// MARK: - Mock WebSocket Service
class MockWebSocketService: ObservableObject {
    @Published var isConnected: Bool = false
    @Published var appLoaded: Bool = false
    @Published var player: Player = Player()
    @Published var person: Person = Person()
    @Published var swipeCharacter: Person? = Person()
    @Published var questionQueue: [Question] = []
    @Published var currentQuestion: Question?
    @Published var currentMessageEvent: MessageEvent?
    @Published var currentError: WebSocketService.WebSocketError?

    // Track sent messages
    var sentMessages: [[String: Any]] = []

    // Track method calls
    var connectCalled = false
    var disconnectCalled = false
    var sendMessageCalled = false

    // Simulated connection delay
    var connectionDelay: TimeInterval = 0.1

    // MARK: - Mock Methods

    func connect() {
        connectCalled = true
        // Simulate async connection
        DispatchQueue.main.asyncAfter(deadline: .now() + connectionDelay) { [weak self] in
            self?.isConnected = true
            self?.appLoaded = true
        }
    }

    func disconnect() {
        disconnectCalled = true
        isConnected = false
    }

    func sendMessage(message: [String: Any]) {
        sendMessageCalled = true
        sentMessages.append(message)
    }

    // MARK: - Test Helpers

    /// Reset all tracked data
    func reset() {
        sentMessages.removeAll()
        questionQueue.removeAll()
        currentQuestion = nil
        currentError = nil
        connectCalled = false
        disconnectCalled = false
        sendMessageCalled = false
        isConnected = false
        appLoaded = false
    }

    /// Simulate receiving a player update message
    func simulatePlayerUpdate(energy: Int? = nil, money: Int? = nil, diamonds: Int? = nil) {
        if let energy = energy {
            person.calcEnergy = energy
        }
        if let money = money {
            person.money = money
        }
        if let diamonds = diamonds {
            person.diamonds = diamonds
        }
    }

    /// Simulate receiving an error message
    func simulateError(_ error: WebSocketService.WebSocketError) {
        currentError = error
    }

    /// Simulate receiving a question
    func simulateQuestion(_ question: Question) {
        questionQueue.append(question)
        currentQuestion = question
    }

    /// Check if a specific message type was sent
    func hasSentMessage(ofType type: String) -> Bool {
        return sentMessages.contains { ($0["type"] as? String) == type }
    }

    /// Get count of messages sent with specific type
    func messageCount(ofType type: String) -> Int {
        return sentMessages.filter { ($0["type"] as? String) == type }.count
    }

    /// Get first message of specific type
    func firstMessage(ofType type: String) -> [String: Any]? {
        return sentMessages.first { ($0["type"] as? String) == type }
    }
}
