//
//  JJPhoneSDK.swift
//  JJPhoneDemo
//
//  面向外部集成方的统一 SDK 入口
//

import UIKit

/// 对外暴露的 SIP 配置
public struct JJPhoneConfig {
    public var serverIP: String
    public var serverPort: String
    public var account: String
    public var password: String
    public var passwordPk: String?
    
    public init(serverIP: String,
                serverPort: String,
                account: String,
                password: String,
                passwordPk: String? = nil) {
        self.serverIP = serverIP
        self.serverPort = serverPort
        self.account = account
        self.password = password
        self.passwordPk = passwordPk
    }
}

/// SDK 回调协议（可选）
public protocol JJPhoneSDKDelegate: AnyObject {
    /// SIP 已连接
    func jjphoneDidConnect()
    /// SIP 已断开
    func jjphoneDidDisconnect()
    /// SIP 连接失败
    func jjphoneConnectFailed(reason: String?)
}

public extension JJPhoneSDKDelegate {
    func jjphoneDidConnect() {}
    func jjphoneDidDisconnect() {}
    func jjphoneConnectFailed(reason: String?) {}
}

/// SDK 对外统一入口
public final class JJPhoneSDK {
    
    public static let shared = JJPhoneSDK()
    
    public weak var delegate: JJPhoneSDKDelegate?
    
    private init() {
        setupNotifications()
    }
    
    // MARK: - 基础能力
    
    /// 初始化底层 VoIP 服务（如未初始化则执行一次）
    @discardableResult
    public func initializeIfNeeded() -> Int {
        return PhoneService.shared.initialize()
    }
    
    /// 更新并缓存配置
    public func updateConfig(_ config: JJPhoneConfig) {
        let phoneConfig = PhoneConfig.shared
        phoneConfig.account = config.account
        phoneConfig.password = config.password
    }
    
    /// 使用配置登录 SIP（内部会执行完整登录流程）
    public func login(config: JJPhoneConfig,
                      completion: ((Result<Void, Error>) -> Void)? = nil) {
        updateConfig(config)
        
        let phoneService = PhoneService.shared
        let initResult = phoneService.initialize()
        if initResult != 0 {
            let error = NSError(
                domain: "JJPhoneSDK",
                code: initResult,
                userInfo: [NSLocalizedDescriptionKey: PhoneService.errorDescription(forCode: initResult)]
            )
            completion?(.failure(error))
            return
        }
        
        // 使用新的登录方法（通过账号密码和环境配置）
        let environment = PhoneConfig.shared.environment
        phoneService.loginWithAccount(
            account: config.account,
            password: config.password,
            environment: environment,
            passwordPk: config.passwordPk,
            statusUpdate: { _ in
                // 状态更新暂不对外透出
            },
            success: { _ in
                // 真正连接结果通过通知回调 delegate
                completion?(.success(()))
            },
            failure: { code, message in
                let error = NSError(
                    domain: "JJPhoneSDK",
                    code: code,
                    userInfo: [NSLocalizedDescriptionKey: message ?? "登录失败"]
                )
                completion?(.failure(error))
            }
        )
    }
    
    /// 登出 SIP
    public func logout() {
        PhoneService.shared.logout()
    }
    
    /// 当前是否可以拨打电话
    public func canMakeCall() -> Bool {
        return PhoneService.shared.canMakeCall()
    }
    
    /// 直接发起一次呼叫（适用于只用服务层的集成方）
    /// - Parameters:
    ///   - number: 被叫号码
    ///   - userData: 自定义数据字典（可选），将作为JSON字符串进行base64编码后添加到P-Call-UserData头传递，编码后长度需小于255字节
    public func makeCall(number: String, userData: [String: Any]? = nil) {
        PhoneService.shared.makeCall(number: number, userData: userData)
    }
    
    // MARK: - 内置 UI 入口
    
    /// 返回内置的通话主界面（带通话记录和拨号入口）
    public func makePhoneMainViewController() -> UIViewController {
        return PhoneMainViewController()
    }
    
    /// 返回内置拨号页面
    public func makeDialViewController() -> UIViewController {
        return DialViewController()
    }
    
    // MARK: - 内部通知转发
    
    private func setupNotifications() {
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleSipConnected),
            name: NSNotification.Name(NSNotification.Name.sipConnected.rawValue),
            object: nil
        )
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleSipDisconnected),
            name: NSNotification.Name(NSNotification.Name.sipDisconnected.rawValue),
            object: nil
        )
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleSipConnectFailed(_:)),
            name: NSNotification.Name(NSNotification.Name.sipConnectFailed.rawValue),
            object: nil
        )
    }
    
    @objc private func handleSipConnected() {
        delegate?.jjphoneDidConnect()
    }
    
    @objc private func handleSipDisconnected() {
        delegate?.jjphoneDidDisconnect()
    }
    
    @objc private func handleSipConnectFailed(_ notification: Notification) {
        let reason = notification.userInfo?[kSIPReasonDescriptionKey] as? String
        delegate?.jjphoneConnectFailed(reason: reason)
    }
}


