import Foundation
import Combine

/// Manages energy refills, time skips, and in-app purchase flows.
class MonetizationService: ObservableObject {
    @Published var energyRefillTiers: [EnergyRefillTier] = []
    @Published var unlimitedEnergyUntil: Date?
    @Published var timeSkipTiers: [TimeSkipTier] = []
    @Published var lastTimeSkipSummary: TimeSkipSummary?
    @Published var purchaseSuccessful: Bool = false
    /// Set on successful in-game store purchase; used for celebration UI.
    @Published var lastStorePurchaseItemId: String?

    weak var facade: WebSocketService?

    func sendMessage(_ message: [String: Any]) {
        facade?.sendMessage(message: message)
    }

    // MARK: - Actions

    func fetchEnergyRefillTiers() {
        sendMessage(WebSocketCommands.getEnergyRefillTiers())
    }

    func purchaseEnergyRefill(tierType: String) {
        sendMessage(WebSocketCommands.purchaseEnergyRefill(refillType: tierType))
    }

    func fetchTimeSkipTiers() {
        sendMessage(WebSocketCommands.getTimeSkipTiers())
    }

    func purchaseTimeSkip(tierType: String) {
        sendMessage(WebSocketCommands.purchaseTimeSkip(skipType: tierType))
    }

    // MARK: - Message Handling

    func handleMessage(type: String, data: [String: Any]) -> Bool {
        switch type {
        case "energyRefillTiers":
            handleEnergyRefillTiers(data)
            return true
        case "purchaseComplete":
            handlePurchaseComplete(data)
            return true
        case "inAppPurchaseComplete":
            handleInAppPurchaseComplete(data)
            return true
        case "timeSkipTiers":
            handleTimeSkipTiers(data)
            return true
        case "timeSkipComplete":
            handleTimeSkipComplete(data)
            return true
        default:
            return false
        }
    }

    // MARK: - Private Handlers

    private func handleEnergyRefillTiers(_ data: [String: Any]) {
        if let tiersData = data["tiers"] as? [String: [String: Int]] {
            self.energyRefillTiers = tiersData.map { (key, value) in
                EnergyRefillTier(
                    type: key,
                    energy: value["energy"] ?? 0,
                    diamonds: value["diamonds"] ?? 0
                )
            }.sorted { $0.diamonds < $1.diamonds }
        }
    }

    private func handlePurchaseComplete(_ data: [String: Any]) {
        #if DEBUG
        if facade == nil { print("MonetizationService.handlePurchaseComplete: facade is nil, balance update will be lost") }
        #endif

        if let itemId = data["itemId"] as? String,
           data["success"] as? Bool ?? true {
            lastStorePurchaseItemId = itemId
            purchaseSuccessful = true
            ToastManager.shared.show(.success, message: data["message"] as? String ?? "Purchase completed!")
            SoundManager.shared.playSound(.purchaseSuccess)
            return
        }

        if let category = data["category"] as? String, category == "energy" {
            if let newBalance = data["newBalance"] as? [String: Any] {
                if let energy = newBalance["energy"] as? Int {
                    facade?.person.calcEnergy = energy
                }
                if let diamonds = newBalance["diamonds"] as? Int {
                    facade?.person.diamonds = diamonds
                }
                if let unlimitedUntil = newBalance["unlimited_until"] as? String {
                    let formatter = ISO8601DateFormatter()
                    self.unlimitedEnergyUntil = formatter.date(from: unlimitedUntil)
                }
            }
            facade?.showEnergyRefillModal = false
            ToastManager.shared.show(.success, message: "Energy refilled!")
            SoundManager.shared.playSound(.purchaseSuccess)
        }
    }

    private func handleInAppPurchaseComplete(_ data: [String: Any]) {
        let success = data["success"] as? Bool ?? false
        if success {
            ToastManager.shared.show(.success, message: "Purchase completed successfully")
            SoundManager.shared.playSound(.purchaseSuccess)
        }
    }

    private func handleTimeSkipTiers(_ data: [String: Any]) {
        if let tiersData = data["tiers"] as? [String: [String: Any]] {
            self.timeSkipTiers = tiersData.compactMap { (key, value) in
                guard let diamonds = value["diamonds"] as? Int else { return nil }
                let duration = (value["durationSeconds"] as? Double) ?? (value["duration"] as? Double)
                return TimeSkipTier(
                    type: key,
                    durationSeconds: duration,
                    diamonds: diamonds
                )
            }.sorted { $0.diamonds < $1.diamonds }
        }
    }

    private func handleTimeSkipComplete(_ data: [String: Any]) {
        #if DEBUG
        if facade == nil { print("MonetizationService.handleTimeSkipComplete: facade is nil, balance update will be lost") }
        #endif
        if let summaryData = data["summary"] as? [String: Any],
           let jsonData = try? JSONSerialization.data(withJSONObject: summaryData),
           let summary = try? JSONDecoder().decode(TimeSkipSummary.self, from: jsonData) {
            self.lastTimeSkipSummary = summary
            facade?.person.diamonds = summary.diamonds
            facade?.showTimeSkipModal = false
            facade?.showTimeSkipSummary = true
            ToastManager.shared.show(.success, message: "Time skipped!")
            SoundManager.shared.playSound(.purchaseSuccess)
        }
    }
}
