//
//  AnalyticsManager.swift
//  lichunWebsocket
//
//  Centralized Firebase Analytics and Crashlytics management
//

import SwiftUI
import Combine

// NOTE: Firebase SDK must be added via Xcode SPM:
// File → Add Packages → https://github.com/firebase/firebase-ios-sdk
// Select: FirebaseAnalytics, FirebaseCrashlytics

#if canImport(FirebaseAnalytics) && canImport(FirebaseCrashlytics)
import FirebaseAnalytics
import FirebaseCrashlytics
#endif

// MARK: - Analytics Event Types
enum AnalyticsEvent {
    // App Lifecycle
    case appLaunched
    case appBackgrounded
    case appForegrounded

    // Onboarding
    case onboardingStepComplete(step: Int)
    case onboardingComplete

    // Character
    case characterCreated(age: Int, gender: String)
    case characterDeath(age: Int, cause: String)

    // Purchases
    case purchaseInitiated(itemId: String, itemName: String, price: Int)
    case purchaseCompleted(itemId: String, itemName: String, price: Int)
    case purchaseFailed(itemId: String, reason: String)
    case iapInitiated(productId: String)
    case iapCompleted(productId: String, revenue: Double)
    case iapFailed(productId: String, reason: String)

    // Activities
    case activityEnrolled(activityId: String, activityType: String, activityName: String)
    case activityPerformed(activityId: String, energyCost: Int)
    case activityQuit(activityId: String, reason: String)
    case jobApplied(jobId: String, jobTitle: String)
    case jobQuit(jobId: String, jobTitle: String)

    // Dating
    case datingSwipe(direction: String, characterId: String)
    case datingMatch(characterId: String)
    case dateStarted(activityName: String, energyCost: Int, moneyCost: Int)
    case giftSent(characterId: String, giftType: String)
    case relationshipStarted(characterId: String, status: String)
    case relationshipEnded(characterId: String, status: String, reason: String)

    // Navigation
    case tabSwitched(from: Int, to: Int)
    case screenViewed(screenName: String, screenClass: String?)

    // WebSocket
    case websocketConnected
    case websocketDisconnected(reason: String)
    case websocketError(errorType: String, message: String)
    case serverError(errorCode: String, message: String)

    // Game Actions
    case gameSpeedChanged(newSpeed: Int)
    case questionAnswered(questionId: String, answer: String)
    case messageReceived(messageType: String)

    var name: String {
        switch self {
        case .appLaunched: return "app_launched"
        case .appBackgrounded: return "app_backgrounded"
        case .appForegrounded: return "app_foregrounded"
        case .onboardingStepComplete: return "onboarding_step_complete"
        case .onboardingComplete: return "onboarding_complete"
        case .characterCreated: return "character_created"
        case .characterDeath: return "character_death"
        case .purchaseInitiated: return "purchase_initiated"
        case .purchaseCompleted: return "purchase_completed"
        case .purchaseFailed: return "purchase_failed"
        case .iapInitiated: return "iap_initiated"
        case .iapCompleted: return "iap_completed"
        case .iapFailed: return "iap_failed"
        case .activityEnrolled: return "activity_enrolled"
        case .activityPerformed: return "activity_performed"
        case .activityQuit: return "activity_quit"
        case .jobApplied: return "job_applied"
        case .jobQuit: return "job_quit"
        case .datingSwipe: return "dating_swipe"
        case .datingMatch: return "dating_match"
        case .dateStarted: return "date_started"
        case .giftSent: return "gift_sent"
        case .relationshipStarted: return "relationship_started"
        case .relationshipEnded: return "relationship_ended"
        case .tabSwitched: return "tab_switched"
        case .screenViewed: return "screen_viewed"
        case .websocketConnected: return "websocket_connected"
        case .websocketDisconnected: return "websocket_disconnected"
        case .websocketError: return "websocket_error"
        case .serverError: return "server_error"
        case .gameSpeedChanged: return "game_speed_changed"
        case .questionAnswered: return "question_answered"
        case .messageReceived: return "message_received"
        }
    }

    var parameters: [String: Any] {
        switch self {
        case .onboardingStepComplete(let step):
            return ["step": step]
        case .characterCreated(let age, let gender):
            return ["age": age, "gender": gender]
        case .characterDeath(let age, let cause):
            return ["age": age, "cause": cause]
        case .purchaseInitiated(let itemId, let itemName, let price):
            return ["item_id": itemId, "item_name": itemName, "price": price]
        case .purchaseCompleted(let itemId, let itemName, let price):
            return ["item_id": itemId, "item_name": itemName, "price": price, "currency": "USD"]
        case .purchaseFailed(let itemId, let reason):
            return ["item_id": itemId, "reason": reason]
        case .iapInitiated(let productId):
            return ["product_id": productId]
        case .iapCompleted(let productId, let revenue):
            return ["product_id": productId, "revenue": revenue, "currency": "USD"]
        case .iapFailed(let productId, let reason):
            return ["product_id": productId, "reason": reason]
        case .activityEnrolled(let activityId, let activityType, let activityName):
            return ["activity_id": activityId, "activity_type": activityType, "activity_name": activityName]
        case .activityPerformed(let activityId, let energyCost):
            return ["activity_id": activityId, "energy_cost": energyCost]
        case .activityQuit(let activityId, let reason):
            return ["activity_id": activityId, "reason": reason]
        case .jobApplied(let jobId, let jobTitle):
            return ["job_id": jobId, "job_title": jobTitle]
        case .jobQuit(let jobId, let jobTitle):
            return ["job_id": jobId, "job_title": jobTitle]
        case .datingSwipe(let direction, let characterId):
            return ["direction": direction, "character_id": characterId]
        case .datingMatch(let characterId):
            return ["character_id": characterId]
        case .dateStarted(let activityName, let energyCost, let moneyCost):
            return ["activity_name": activityName, "energy_cost": energyCost, "money_cost": moneyCost]
        case .giftSent(let characterId, let giftType):
            return ["character_id": characterId, "gift_type": giftType]
        case .relationshipStarted(let characterId, let status):
            return ["character_id": characterId, "status": status]
        case .relationshipEnded(let characterId, let status, let reason):
            return ["character_id": characterId, "status": status, "reason": reason]
        case .tabSwitched(let from, let to):
            return ["from_tab": from, "to_tab": to]
        case .screenViewed(let screenName, let screenClass):
            var params: [String: Any] = ["screen_name": screenName]
            if let screenClass = screenClass {
                params["screen_class"] = screenClass
            }
            return params
        case .websocketDisconnected(let reason):
            return ["reason": reason]
        case .websocketError(let errorType, let message):
            return ["error_type": errorType, "message": message]
        case .serverError(let errorCode, let message):
            return ["error_code": errorCode, "message": message]
        case .gameSpeedChanged(let newSpeed):
            return ["new_speed": newSpeed]
        case .questionAnswered(let questionId, let answer):
            return ["question_id": questionId, "answer": answer]
        case .messageReceived(let messageType):
            return ["message_type": messageType]
        default:
            return [:]
        }
    }
}

// MARK: - Analytics Manager
class AnalyticsManager: ObservableObject {
    static let shared = AnalyticsManager()

    @Published var isEnabled: Bool {
        didSet {
            UserDefaults.standard.set(isEnabled, forKey: "analyticsEnabled")
            #if canImport(FirebaseAnalytics)
            Analytics.setAnalyticsCollectionEnabled(isEnabled)
            #endif
        }
    }

    private init() {
        // Load analytics preference from UserDefaults
        self.isEnabled = UserDefaults.standard.object(forKey: "analyticsEnabled") as? Bool ?? true
    }

    // MARK: - Public API

    /// Track an analytics event
    func track(_ event: AnalyticsEvent) {
        guard isEnabled else { return }

        #if canImport(FirebaseAnalytics)
        Analytics.logEvent(event.name, parameters: event.parameters)

        // Log to console in debug mode
        #if DEBUG
        print("📊 Analytics: \(event.name)")
        if !event.parameters.isEmpty {
            print("   Parameters: \(event.parameters)")
        }
        #endif
        #else
        // Fallback logging when Firebase is not available
        print("📊 Analytics (No Firebase): \(event.name) - \(event.parameters)")
        #endif
    }

    /// Track screen view with optional screen class
    func trackScreenView(_ screenName: String, screenClass: String? = nil) {
        track(.screenViewed(screenName: screenName, screenClass: screenClass))

        #if canImport(FirebaseAnalytics)
        var parameters: [String: Any] = [
            AnalyticsParameterScreenName: screenName
        ]
        if let screenClass = screenClass {
            parameters[AnalyticsParameterScreenClass] = screenClass
        }
        Analytics.logEvent(AnalyticsEventScreenView, parameters: parameters)
        #endif
    }

    /// Set user ID for analytics
    func setUserID(_ userID: String?) {
        #if canImport(FirebaseAnalytics)
        Analytics.setUserID(userID)

        #if DEBUG
        print("📊 Analytics: Set User ID - \(userID ?? "nil")")
        #endif
        #endif
    }

    /// Set user property
    func setUserProperty(_ value: String?, forName name: String) {
        #if canImport(FirebaseAnalytics)
        Analytics.setUserProperty(value, forName: name)

        #if DEBUG
        print("📊 Analytics: Set User Property - \(name): \(value ?? "nil")")
        #endif
        #endif
    }

    /// Record error to Crashlytics
    func recordError(_ error: Error, additionalInfo: [String: Any]? = nil) {
        #if canImport(FirebaseCrashlytics)
        let crashlytics = Crashlytics.crashlytics()

        // Add additional info as custom keys
        if let info = additionalInfo {
            for (key, value) in info {
                crashlytics.setCustomValue(value, forKey: key)
            }
        }

        // Record the error
        crashlytics.record(error: error)

        #if DEBUG
        print("💥 Crashlytics: Recorded error - \(error.localizedDescription)")
        if let info = additionalInfo {
            print("   Additional Info: \(info)")
        }
        #endif
        #else
        // Fallback logging when Firebase is not available
        print("💥 Error (No Crashlytics): \(error.localizedDescription)")
        if let info = additionalInfo {
            print("   Additional Info: \(info)")
        }
        #endif
    }

    /// Log message for breadcrumb trail in Crashlytics
    func log(_ message: String) {
        #if canImport(FirebaseCrashlytics)
        Crashlytics.crashlytics().log(message)

        #if DEBUG
        print("🍞 Crashlytics Breadcrumb: \(message)")
        #endif
        #else
        // Fallback logging when Firebase is not available
        print("🍞 Log (No Crashlytics): \(message)")
        #endif
    }

    /// Enable or disable analytics collection
    func setAnalyticsEnabled(_ enabled: Bool) {
        isEnabled = enabled
    }

    // MARK: - Convenience Methods

    /// Track app lifecycle events
    func trackAppLifecycle(_ state: String) {
        switch state {
        case "launched":
            track(.appLaunched)
        case "backgrounded":
            track(.appBackgrounded)
        case "foregrounded":
            track(.appForegrounded)
        default:
            break
        }
    }
}

// MARK: - Preview
#if DEBUG
struct AnalyticsManager_Previews: PreviewProvider {
    static var previews: some View {
        VStack(spacing: AppSpacing.lg) {
            Text("Analytics Manager")
                .font(.appTitle)

            Button("Track Screen View") {
                AnalyticsManager.shared.trackScreenView("preview_screen")
            }
            .padding()

            Button("Track Purchase") {
                AnalyticsManager.shared.track(.purchaseCompleted(
                    itemId: "item_123",
                    itemName: "Golden Watch",
                    price: 500
                ))
            }
            .padding()

            Button("Track Onboarding Complete") {
                AnalyticsManager.shared.track(.onboardingComplete)
            }
            .padding()

            Button("Record Test Error") {
                let error = NSError(domain: "TestDomain", code: 123, userInfo: [
                    NSLocalizedDescriptionKey: "Test error for preview"
                ])
                AnalyticsManager.shared.recordError(error, additionalInfo: [
                    "context": "preview",
                    "test": true
                ])
            }
            .padding()

            Button("Log Breadcrumb") {
                AnalyticsManager.shared.log("User tapped test button in preview")
            }
            .padding()
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(AppColors.background)
    }
}
#endif
