//
//  AppDelegate.swift
//  JJPhoneDemo
//
//

import UIKit
import AVFoundation

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 在应用启动时立即配置 AVAudioSession（在 PJSIP 初始化之前）
        configureAudioSessionEarly()
        
        // 配置 VoIP 日志等级（必须在初始化之前设置）
        configureVoIPLogging()
        
        // 可选：提前初始化 VoIP（也可以延迟到登录时）
        JJPhoneSDK.shared.initializeIfNeeded()
        
        window = UIWindow(frame: UIScreen.main.bounds)
        if #available(iOS 13.0, *) {
            window?.backgroundColor = .systemBackground
        } else {
            window?.backgroundColor = .white
        }
        
        // 使用 SDK 提供的 UI 作为入口
        let phoneVC = JJPhoneSDK.shared.makePhoneMainViewController()
        let nav = UINavigationController(rootViewController: phoneVC)
        
        window?.rootViewController = nav
        window?.makeKeyAndVisible()
        
        // 监听 Socket.IO 通话状态通知
        setupSocketCallStatusNotification()
        
        return true
    }
    
    /// 设置 Socket.IO 通话状态通知监听
    private func setupSocketCallStatusNotification() {
        // 使用头文件中定义的常量 kSocketCallStatusNotification
        let notificationName = NSNotification.Name(NSNotification.Name.socketCallStatus.rawValue)
        AppLogger.info("开始监听 Socket.IO 通话状态通知: \(notificationName.rawValue)", category: "AppDelegate")
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleSocketCallStatusNotification(_:)),
            name: notificationName,
            object: nil
        )
    }
    
    /// 处理 Socket.IO 通话状态通知
    @objc private func handleSocketCallStatusNotification(_ notification: Notification) {
        AppLogger.info("收到 Socket.IO 通话状态通知: name=\(notification.name.rawValue)", category: "AppDelegate")
        
        guard let userInfo = notification.userInfo else {
            AppLogger.warning("Socket.IO 通话状态通知没有 userInfo", category: "AppDelegate")
            return
        }
        
        // 详细输出 userInfo 的所有内容
        AppLogger.info("通知 userInfo 完整内容: \(userInfo)", category: "AppDelegate")
        for (key, value) in userInfo {
            AppLogger.info("  - key: \(key), value: \(value), type: \(type(of: value))", category: "AppDelegate")
        }
        
        // 尝试多种可能的 key 名称
        let possibleCallTypeKeys = [kSocketCallTypeKey, "callType", "socketCallType", "type"]
        var callType: String? = nil
        
        for key in possibleCallTypeKeys {
            if let value = userInfo[key] as? String {
                callType = value
                AppLogger.info("找到 callType (key=\(key)): \(value)", category: "AppDelegate")
                break
            } else if let value = userInfo[key] {
                AppLogger.info("key \(key) 存在但类型不对: \(value), type: \(type(of: value))", category: "AppDelegate")
            }
        }
        
        guard let finalCallType = callType else {
            AppLogger.warning("Socket.IO 通话状态通知没有找到 callType，尝试所有可能的 key 都失败", category: "AppDelegate")
            // 即使没有 callType，也尝试显示页面（可能是其他状态的通知）
            AppLogger.info("尝试显示通话页面（即使没有 callType）", category: "AppDelegate")
            handleCallStatusNotification(userInfo: userInfo, callType: nil)
            return
        }
        
        AppLogger.info("通话类型: \(finalCallType)", category: "AppDelegate")
        
        // 处理来电（callin）和呼出（callout），因为从坐席角度看，callout 也需要显示通话页面
        // 只有当 callType 既不是 callin 也不是 callout 时才跳过
        guard finalCallType == "callin" || finalCallType == "callout" else {
            AppLogger.info("不是通话类型，跳过处理: callType=\(finalCallType)", category: "AppDelegate")
            return
        }
        
        AppLogger.info("处理通话通知: callType=\(finalCallType)", category: "AppDelegate")
        handleCallStatusNotification(userInfo: userInfo, callType: finalCallType)
    }
    
    /// 处理通话状态通知的通用方法
    private func handleCallStatusNotification(userInfo: [AnyHashable: Any], callType: String?) {
        
        // 尝试多种可能的 key 名称来获取数据
        let possibleKeys: [String: [String]] = [
            "callState": [kSocketCallStateKey, "callState", "socketCallState", "state"],
            "callStateName": [kSocketCallStateNameKey, "callStateName", "socketCallStateName", "stateName"],
            "customerNumber": [kSocketCustomerNumberKey, "customerNumber", "socketCustomerNumber", "number", "phoneNumber"],
            "callId": [kSocketCallIdKey, "callId", "socketCallId", "id"]
        ]
        
        func getValue(for key: String, possibleKeys: [String]) -> Any? {
            for possibleKey in possibleKeys {
                if let value = userInfo[possibleKey] {
                    AppLogger.info("找到 \(key) (使用 key=\(possibleKey)): \(value)", category: "AppDelegate")
                    return value
                }
            }
            AppLogger.warning("未找到 \(key)，尝试了所有可能的 key: \(possibleKeys)", category: "AppDelegate")
            return nil
        }
        
        let callStateValue = getValue(for: "callState", possibleKeys: possibleKeys["callState"] ?? [])
        let callState = (callStateValue as? Int) ?? (callStateValue as? String).flatMap { Int($0) } ?? 0
        let callStateName = getValue(for: "callStateName", possibleKeys: possibleKeys["callStateName"] ?? []) as? String ?? ""
        let customerNumber = getValue(for: "customerNumber", possibleKeys: possibleKeys["customerNumber"] ?? []) as? String ?? ""
        let callId = getValue(for: "callId", possibleKeys: possibleKeys["callId"] ?? []) as? String ?? ""
        
        AppLogger.info("解析结果: callId=\(callId), callType=\(callType ?? "nil"), callState=\(callState), customerNumber=\(customerNumber)", category: "AppDelegate")
        
        // 在主线程处理 UI
        DispatchQueue.main.async { [weak self] in
            self?.showIncomingCallPage(callId: callId, customerNumber: customerNumber, callState: callState, callStateName: callStateName, callType: callType)
        }
    }
    
    /// 显示通话页面（支持来电和呼出）
    private func showIncomingCallPage(callId: String, customerNumber: String, callState: Int, callStateName: String, callType: String?) {
        // 获取当前显示的视图控制器
        guard let window = window,
              let rootViewController = window.rootViewController else {
            AppLogger.warning("无法获取根视图控制器，无法显示来电页面", category: "AppDelegate")
            return
        }
        
        // 查找导航控制器
        var navigationController: UINavigationController?
        
        if let nav = rootViewController as? UINavigationController {
            navigationController = nav
        } else if let presented = rootViewController.presentedViewController as? UINavigationController {
            navigationController = presented
        } else if let tabBar = rootViewController as? UITabBarController,
                   let selected = tabBar.selectedViewController as? UINavigationController {
            navigationController = selected
        }
        
        guard let nav = navigationController else {
            AppLogger.warning("无法找到导航控制器，无法显示来电页面", category: "AppDelegate")
            return
        }
        
        // 检查是否已经显示了通话页面
        if let topVC = nav.topViewController as? ActiveCallViewController {
            AppLogger.info("通话页面已显示，跳过", category: "AppDelegate")
            return
        }
        
        // 创建通话记录
        let call = Call()
        call.id = callId
        call.phoneNumber = customerNumber
        // 根据 callType 设置通话类型：callin 是来电，callout 是呼出
        if let callTypeStr = callType, callTypeStr == "callin" {
            call.callType = .incoming
        } else {
            // 默认或 callout 都设置为呼出
            call.callType = .outgoing
        }
        
        // 根据通话状态设置初始状态
        // 通常 callState 1 表示来电，2 表示振铃，3 表示接通等
        if callState == 1 || callState == 2 {
            call.status = .connecting  // 振铃中
        } else if callState == 3 {
            call.status = .connected  // 已接通
        } else {
            call.status = .calling  // 默认正在呼叫
        }
        
        // 创建并显示通话页面
        let callVC = ActiveCallViewController()
        callVC.call = call
        nav.pushViewController(callVC, animated: true)
        
        AppLogger.info("已显示来电页面: customerNumber=\(customerNumber), callState=\(callState)", category: "AppDelegate")
    }
    
    /// 在应用启动时提前配置 AVAudioSession
    private func configureAudioSessionEarly() {
        do {
            let audioSession = AVAudioSession.sharedInstance()
            
            // 配置音频会话类别（默认使用听筒模式，不设置 .defaultToSpeaker）
            try audioSession.setCategory(
                .playAndRecord,
                mode: .voiceChat,
                options: [.allowBluetooth, .allowBluetoothA2DP, .duckOthers]
            )
            
            // 激活音频会话
            try audioSession.setActive(true, options: [])
            
            // 请求麦克风权限（异步，不阻塞启动）
            audioSession.requestRecordPermission { granted in
                if !granted {
                    AppLogger.warning("Microphone permission denied", category: "AppDelegate")
                }
            }
        } catch {
            AppLogger.error("AVAudioSession configuration failed - \(error.localizedDescription)", category: "AppDelegate")
        }
    }
    
    /// 配置 VoIP 日志系统
    private func configureVoIPLogging() {
        // 设置日志等级为 Verbose (2)，输出所有日志（业务、SIP、错误）
        VoIPManager.setLogLevel(2)
        
        // 启用文件日志
        VoIPManager.setFileLoggingEnabled(true)
        
        // 使用默认日志路径：Documents/VoIPLogs/voip.log
        // PJSIP 日志会自动生成在同一目录：Documents/VoIPLogs/voip_pjsip.log
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }

}

