//
//  SplashAdViewController.swift
//  VenusKitto
//
//  Created by Neoa on 2025/1/27.
//

import UIKit
import AnyThinkSplash
import AnyThinkSDK

class SplashAdViewController: UIViewController, ATSplashDelegate {
    
    // MARK: - Properties
    private let splashPlacementID = "b68d88cc420248" // 开屏广告placement ID
    private var splashAd: ATSplash?
    private var isAdLoaded = false
    private var useFootLogoView = false // 是否使用底部Logo视图
    
    // 广告展示开始时间（毫秒）
    private var adStartTime: Int64 = 0
    
    // 回调闭包，用于广告结束后跳转到主界面
    var onSplashAdFinished: (() -> Void)?
    
    // MARK: - Initialization
    convenience init(useFootLogoView: Bool = false) {
        self.init()
        self.useFootLogoView = useFootLogoView
    }
    
    // MARK: - UI Components
    private let backgroundImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.image = UIImage(named: "catlogos")
        imageView.contentMode = .scaleAspectFit
        imageView.translatesAutoresizingMaskIntoConstraints = false
        return imageView
    }()
    
    private let appNameLabel: UILabel = {
        let label = UILabel()
        label.text = "VenusKitto"
        label.font = UIFont.systemFont(ofSize: 24, weight: .bold)
        label.textColor = UIColor(hex: "#2B2B2B")
        label.textAlignment = .center
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    // MARK: - Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor(hex: "#FFFEFC")
        loadSplashAd()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    }
    // MARK: - Actions
    
    // MARK: - Splash Ad Methods
    private func loadSplashAd() {
        var loadConfigDict: [AnyHashable: Any] = [:]
        
        // 开屏超时时间
        loadConfigDict[kATSplashExtraTolerateTimeoutKey] = NSNumber(value: 5)
        // 自定义load参数
        loadConfigDict[kATAdLoadingExtraMediaExtraKey] = "media_val_SplashVC"
        
        // 可选接入，如果使用了腾讯优量汇(GDT)，可添加以下配置
        // AdLoadConfigTool.splash_loadExtraConfigAppend_Tencent(&loadConfigDict)
        
        ATAdManager.shared().loadAD(withPlacementID: splashPlacementID, extra: loadConfigDict, delegate: self, containerView: nil)
    }
    
    
    private func showSplashAd() {
        // 场景统计功能，可选接入
        ATAdManager.shared().entrySplashScenario(withPlacementID: splashPlacementID, scene: "")
        
        // 检查是否有就绪
        guard ATAdManager.shared().splashReady(forPlacementID: splashPlacementID) else {
            loadSplashAd()
            return
        }
        
        // 展示配置
        let config = ATShowConfig(scene: "", showCustomExt: "testShowCustomExt")
        
        // 开屏相关参数配置
        let configDict: [AnyHashable: Any] = [:]
        
        // 展示广告,在App原window中展示
        ATAdManager.shared().showSplash(withPlacementID: splashPlacementID, config: config, window: view.window!, in: self, extra: configDict, delegate: self)
        
        // 记录广告展示时间
        adStartTime = nowMillis()
        incrementTodayAdCount()
    }

    
    private func finishSplashAd() {
        // 调用回调，跳转到主界面
        onSplashAdFinished?()
    }
    
    // MARK: - Helper Methods
    private func nowMillis() -> Int64 {
        Int64(Date().timeIntervalSince1970 * 1000)
    }
    
    private func incrementTodayAdCount() {
        let df = DateFormatter()
        df.locale = Locale(identifier: "en_US_POSIX")
        df.dateFormat = "yyyy-MM-dd"
        let key = "adCount_" + df.string(from: Date())
        let current = UserDefaults.standard.integer(forKey: key)
        UserDefaults.standard.set(current + 1, forKey: key)
    }
}

// MARK: - ATAdLoadingDelegate
extension SplashAdViewController: ATAdLoadingDelegate {
    /// 开屏广告加载完成
    func didFinishLoadingSplashAD(withPlacementID placementID: String, isTimeout: Bool) {
        print("开屏加载成功:\(placementID)----是否超时:\(isTimeout)")
        isAdLoaded = true
        if !isTimeout {
            // 没有超时，展示开屏广告
            showSplashAd()
        } else {
            // 加载成功，但超时了
            finishSplashAd()
        }
    }
    
    /// 广告位加载失败
    func didFailToLoadAD(withPlacementID placementID: String, error: Error) {
        print("didFailToLoadADWithPlacementID:\(placementID) error:\(error)")
        // 所有广告源加载失败了，进入首页
        finishSplashAd()
    }
    
    /// 开屏广告加载超时
    func didTimeoutLoadingSplashAD(withPlacementID placementID: String) {
        print("didTimeoutLoadingSplashADWithPlacementID:\(placementID)")
        // 超时了，首页加载完成后进入首页
        finishSplashAd()
    }
    
    /// 获得展示收益
    func didRevenue(forPlacementID placementID: String, extra: [AnyHashable : Any]!) {
        print("didRevenueForPlacementID:\(placementID) with extra: \(extra ?? [:])")
        uploadAdRevenue(placementID: placementID, extra: extra ?? [:])
    }
    
    /// 加载成功且加载流程完毕
    func didFinishLoadingAD(withPlacementID placementID: String) {
        print("didFinishLoadingADWithPlacementID:\(placementID)")
    }
}

// MARK: - ATSplashDelegate
extension SplashAdViewController {
    /// 开屏广告已展示
    func splashDidShow(forPlacementID placementID: String, extra: [AnyHashable : Any]!) {
        print("splashDidShowForPlacementID:\(placementID)")
        // 展示广告后可以隐藏，避免遮挡
        // 这里可以隐藏loading view
    }
    
    /// 开屏广告已关闭
    func splashDidClose(forPlacementID placementID: String, extra: [AnyHashable : Any]!) {
        print("splashDidCloseForPlacementID:\(placementID) extra:\(extra ?? [:])")
        // 进入首页
        finishSplashAd()
    }
    
    /// 开屏广告已点击
    func splashDidClick(forPlacementID placementID: String, extra: [AnyHashable : Any]!) {
        print("splashDidClickForPlacementID:\(placementID)")
    }
    
    /// 开屏广告展示失败
    func splashDidShowFailed(forPlacementID placementID: String, error: Error, extra: [AnyHashable : Any]!) {
        print("splashDidShowFailedForPlacementID:\(placementID) error:\(error)")
        // 没有展示成功,也进入首页,注意控制重复跳转
        finishSplashAd()
    }
    
    /// 开屏广告已打开或跳转深链接页面
    func splashDeepLinkOrJump(forPlacementID placementID: String, extra: [AnyHashable : Any]!, result success: Bool) {
        print("splashDeepLinkOrJumpForPlacementID:placementID:\(placementID)")
    }
    
    /// 开屏广告详情页已关闭
    func splashDetailDidClosed(forPlacementID placementID: String, extra: [AnyHashable : Any]!) {
        print("splashDetailDidClosedForPlacementID:\(placementID)")
        // 可在此获取关闭原因:dismiss_type
        // 热启动预加载（可选）
        // loadSplashAd()
    }
    
    /// 开屏广告关闭计时
    func splashCountdownTime(_ countdown: Int, forPlacementID placementID: String, extra: [AnyHashable : Any]!) {
        print("splashCountdownTime:\(countdown) forPlacementID:\(placementID)")
    }
    
    /// 开屏广告zoomout view已点击，仅Pangle 腾讯优量汇 V+支持
    func splashZoomOutViewDidClick(forPlacementID placementID: String, extra: [AnyHashable : Any]!) {
        print("splashZoomOutViewDidClickForPlacementID:\(placementID)")
    }
    
    /// 开屏广告zoomout view已关闭，仅Pangle 腾讯优量汇 V+支持
    func splashZoomOutViewDidClose(forPlacementID placementID: String, extra: [AnyHashable : Any]!) {
        print("splashZoomOutViewDidCloseForPlacementID:\(placementID)")
    }
}

// MARK: - Ad Revenue Upload
extension SplashAdViewController {
    private func uploadAdRevenue(placementID: String, extra: [AnyHashable: Any]) {
        // 计算 begin / finish（毫秒）并格式化为 "yyyy-MM-dd HH:mm:ss"
        let beginMs = adStartTime
        let finishMs = nowMillis()
        let beginTime = formatMillisToString(beginMs)
        let finishTime = formatMillisToString(finishMs)
        
        // 将 AnyHashable-key 的字典转为 String-key，且递归转为 JSON 可序列化类型
        func jsonSafe(_ value: Any) -> Any {
            if value is String || value is NSNumber || value is NSNull { return value }
            if let d = value as? [String: Any] { return d.mapValues { jsonSafe($0) } }
            if let d = value as? [AnyHashable: Any] {
                var nd: [String: Any] = [:]
                d.forEach { nd[String(describing: $0.key)] = jsonSafe($0.value) }
                return nd
            }
            if let arr = value as? [Any] { return arr.map { jsonSafe($0) } }

            if let v = value as? NSValue {
                // 处理常见 CoreGraphics 结构体；其余转描述串
                let type = String(cString: v.objCType)
                #if canImport(CoreGraphics)
                if type == "{CGSize=dd}" {
                    let s = v.cgSizeValue
                    return ["width": s.width, "height": s.height]
                } else if type == "{CGPoint=dd}" {
                    let p = v.cgPointValue
                    return ["x": p.x, "y": p.y]
                } else if type == "{CGRect={CGPoint=dd}{CGSize=dd}}" {
                    let r = v.cgRectValue
                    return ["x": r.origin.x, "y": r.origin.y, "width": r.size.width, "height": r.size.height]
                }
                #endif
                return v.description
            }

            if let date = value as? Date { return ISO8601DateFormatter().string(from: date) }
            if let url = value as? URL { return url.absoluteString }
            return String(describing: value)
        }

        // 注意：这里用 jsonSafe 处理每个值
        var extraDict: [String: Any] = [:]
        extra.forEach { (k, v) in
            extraDict[String(describing: k)] = jsonSafe(v)
        }

        // 便捷取值工具
        func str(_ key: String) -> String {
            if let v = extraDict[key] { return String(describing: v) }
            return ""
        }
        func intVal(_ key: String) -> Int {
            if let v = extraDict[key] as? Int { return v }
            if let s = extraDict[key] as? String, let i = Int(s) { return i }
            if let d = extraDict[key] as? Double { return Int(d) }
            return 0
        }
        func dbl(_ key: String) -> Double {
            if let v = extraDict[key] as? Double { return v }
            if let s = extraDict[key] as? String, let d = Double(s) { return d }
            if let i = extraDict[key] as? Int { return Double(i) }
            return 0
        }

        // —— 字段映射（对齐安卓） ——
        // adSourceId
        let adSourceId = intVal("adsource_id")
        // networkFormId / networkName / networkPlacementId
        let networkFormId = intVal("network_firm_id")
        let networkName = str("network_name")
        let networkPlacementId = str("network_placement_id")

        // placementId（iOS 回传里一般是 adunit_id；若无，用回调给的 placementID）
        let placementIdValue = str("adunit_id").isEmpty ? placementID : str("adunit_id")

        // recordId（有的 key 叫 requestId，也可能是 req_id，兜底）
        let recordId = str("requestId").isEmpty ? str("req_id") : str("requestId")

        // revenue（publisher_revenue）
        let revenue = dbl("publisher_revenue")

        // userId / nickName
//        let userId = UserDefaults.standard.string(forKey: "roleID") ?? ""
        let nickName = UserDefaults.standard.string(forKey: "memberName") ?? ""

        // ecpm：优先取 adsource_price；若没有，用 revenue*1000 估算一个（单位同 revenue）
        var ecpmStr = str("adsource_price")
        if ecpmStr.isEmpty {
            let ecpm = revenue * 1000.0
            ecpmStr = String(format: "%.6f", ecpm)
        }

        // adSourceIndex / adSourceType（优先 adsource_bid_type: 0=非竞价, 1=竞价）
        let adSourceIndex = intVal("adsource_index")
        // adSourceType 依据 adunit_format 映射：Native->0, RewardedVideo->1, Banner->2, Interstitial->3, Splash->4
        let adUnitFormatRaw = str("adunit_format")
        let adUnitFormat = adUnitFormatRaw.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
        let adSourceType: Int
        switch adUnitFormat {
        case "native":
            adSourceType = 0
        case "rewardedvideo", "rewarded_video", "rewarded":
            adSourceType = 1
        case "banner":
            adSourceType = 2
        case "interstitial":
            adSourceType = 3
        case "splash":
            adSourceType = 4
        default:
            // 兜底逻辑：保持原有取值（若 SDK 提供 adsource_bid_type 则沿用）
            adSourceType = intVal("adsource_bid_type")
        }

        // resultJson：把 SDK 回传完整塞进去，便于排查
        let resultJsonData = try? JSONSerialization.data(withJSONObject: extraDict, options: [])
        let resultJson = resultJsonData.flatMap { String(data: $0, encoding: .utf8) } ?? "{}"
        
        // appId：iOS 若无可用 App ID，可用 Bundle Identifier 兜底
        let appId = kTakuAppID

        let adCount = todayAdCount()
        
        // 组装请求体（与安卓 map 字段完全一致）
        let body: [String: Any] = [
            "adSourceId": adSourceId,
            "beginTime": beginTime,
            "finishTime": finishTime,
            "networkFormId": networkFormId,
            "networkName": networkName,
            "networkPlacementId": networkPlacementId,
            "nickName": nickName,
            "placementId": placementIdValue,
            "recordId": recordId,
            "revenue": revenue,
            "userId": "",
            "ecpm": ecpmStr,
            "adSourceIndex": adSourceIndex,
            "adSourceType": adSourceType,
            "resultJson": resultJson,
            "appId": appId,
            "adCount": adCount,
            "iosId": UIDevice.current.identifierForVendor?.uuidString ?? "", //iOS 设备id
            "begintimestamp": beginMs,
            "finishtimestamp": finishMs
        ]
        
        // 发起上报
        let urlString = "\(baseURL)/ad/saveRecord"
        guard let url = URL(string: urlString) else {
            print("[AD-Upload] URL 无效: \(urlString)")
            return
        }

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: [])

        if let body = request.httpBody,
           let bodyString = String(data: body, encoding: .utf8) {
            print("[AD-Upload] Request URL: \(url)")
            print("[AD-Upload] Request Headers: \(request.allHTTPHeaderFields ?? [:])")
            print("[AD-Upload] Request Body: \(bodyString)")
        }

        
        URLSession.shared.dataTask(with: request) { data, response, error in
            if let error = error {
                print("[AD-Upload] 网络错误: \(error.localizedDescription)")
                return
            }
            if let http = response as? HTTPURLResponse {
                print("[AD-Upload] 响应状态码: \(http.statusCode)")
            }

            if let data = data, let s = String(data: data, encoding: .utf8) {
                print("[AD-Upload] 响应: \(s)")
            }
        }.resume()
    }
    
    // 将毫秒时间戳格式化为 "yyyy-MM-dd HH:mm:ss"
    private func formatMillisToString(_ ms: Int64) -> String {
        let date = Date(timeIntervalSince1970: TimeInterval(ms) / 1000.0)
        let df = DateFormatter()
        df.locale = Locale(identifier: "en_US_POSIX")
        df.timeZone = TimeZone.current
        df.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return df.string(from: date)
    }
    
    // ===== 当天广告观看次数（持久化到 UserDefaults）=====
    private func todayAdCount() -> Int {
        let df = DateFormatter()
        df.locale = Locale(identifier: "en_US_POSIX")
        df.dateFormat = "yyyy-MM-dd"
        let key = "adCount_" + df.string(from: Date())
        return UserDefaults.standard.integer(forKey: key)
    }
}
