//
//  TSGenerateBaseOperation.swift
//  AIRingtone
//
//  Created by 100Years on 2025/3/24.
//

import Combine
import Alamofire


extension Notification.Name {
    static let kBaseOperationQueueCountChanged = Notification.Name("kBaseOperationQueueCountChanged") //任务数量放生变化
    static let kGenerateBasePhotoOperation = Notification.Name("TSGenerateBasePhotoOperation") //生成图生图任务发生变化
    

    static let kAIPhotoDataChanged = Notification.Name("kGenerateBasePhotoChanged") //生成图片数据发生改变
}


class TSGenerateBaseOperationQueue: TSBaseOperationQueue {
    // 存储每个操作的 AnyCancellable
    var stateables: [String: AnyCancellable] = [:]
    
    var generateOperationStateChanged:((String)->Void)?
    override func clearOperationsData(uuid: String) {
        super.clearOperationsData(uuid: uuid)
        stateables.removeValue(forKey: uuid)
    }
    
//    override func cancelOperations(uuid: String) {
//        super.cancelOperations(uuid: uuid)
//        stateables.removeValue(forKey: uuid)
//    }

    func handleStateDatauPblished(uuid:String,generateOperation: TSGenerateBaseOperation,notificationName:Notification.Name) {
        stateables[uuid] = generateOperation.$stateDatauPblished.sink { [weak self] state in
            guard let self = self else { return }
            DispatchQueue.main.async {
                self.generateOperationStateChanged?(uuid)
                
                let uuidData = self.getUUIDData(uuid: uuid)
                NotificationCenter.default.post(
                    name: notificationName,
                    object: nil,
                    userInfo: [
                        "uuid": uuid,
                        "count":self.queue.maxConcurrentOperationCount,
                        "state":uuidData.0,
                        "actionInfo":uuidData.1,
                    ])
            }
        }
    }
    
    func getUUIDData(uuid:String)->(TSProgressState,TSActionInfoModel?){
        return (.none,TSActionInfoModel())
    }
    
}

class TSGenerateBaseOperation: TSBaseOperation , @unchecked Sendable{
    var actionInfoDict:[String:Any]{
        return [:]
    }
    
    @Published var stateDatauPblished:(TSProgressState,TSActionInfoModel?) = (TSProgressState.none,nil){
        didSet{
            dePrint("TSBaseOperation stateDatauPblished didSet = \(stateDatauPblished)")
            if case .start = stateDatauPblished.0 {
                start()
            }else if stateDatauPblished.0.isResult {
                DispatchQueue.main.asyncAfter(deadline: .now()+0.3){//稍微延迟,让通知报成功状态发送出去
                    self.finished()
                }
            }
        }
    }
    
    var queryRequest:Request?
    var stopNetwork = false
    var generatingProgress = 0
    var action_id:Int = 0
    var retryDownloadCount = 0
    public var isShowSuccessView:Bool = false //是否展示成功后的 View 提醒
    var isSaveProcessToDB:Bool = false //是否保存过程到数据库
    {
        didSet{
            if isSaveProcessToDB == true {
                saveDataDB()
            }
        }
    }

    var currentActionInfoModelChanged:((TSActionInfoModel)->Void)?
    var processProgressChanged:((Float)->Void)?
    @Published var currentActionInfoModel: TSActionInfoModel = TSActionInfoModel()
    
    func initializeActionInfoModel(oldModel:TSActionInfoModel) {
        currentActionInfoModel = oldModel
        replaceSaveInfoModel(model: currentActionInfoModel)
        stateDatauPblished = (.start,currentActionInfoModel)
    }
    
    func replaceSaveInfoModel(model:TSActionInfoModel){ }
    
    func handleGenerateSuccess(){}
    func saveDataDB(){}
    
    func backstageGeneration(){
        isSaveProcessToDB = true
        isShowSuccessView = true
    }

    func handleFailInfoModel(errorString:String?,code:Int = 0){
        self.currentActionInfoModel.actionStatus = .failed
        self.currentActionInfoModel.status = "failed"
        generatingProgress = 0
        self.replaceSaveInfoModel(model: self.currentActionInfoModel)
        self.stateDatauPblished = (TSProgressState.getFailed(errorString ?? "",code),self.currentActionInfoModel)
    }
    
    func getActionInfo(oldModel:TSActionInfoModel) {
        currentActionInfoModel = oldModel
        self.getActionInfo(action_id:oldModel.id)
    }

    func getActionInfo(action_id:Int){
        self.action_id = action_id
        queryRequest = TSNetworkShared.get(urlType: .actionInfo,parameters: ["action_id":action_id]) { [weak self] data,error in
            guard let self = self else { return }
            
            if stopNetwork == true {
                return
            }
            
            if let error = error {
                debugPrint("getActionInfo error error = \(error)")
                handleFailInfoModel(errorString: error.tsDesc,code: error.tsCode)
                return
            }
            
            if let result = kNetWorkResultSuccess(data: data) {
                if let infoModel = TSActionInfoModel(JSON: result) {
                    
                    if infoModel.actionStatus != .success {
                        self.replaceSaveInfoModel(model: infoModel)
                    }
                    
                    switch infoModel.actionStatus {
                    case .success:
                        if URL(string:infoModel.response.resultUrl) != nil {
                            downResultUrl(infoModel: infoModel)
                        }else{
                            handleSuccess(infoModel: infoModel)
                        }
                    case .failed:
                        debugPrint("getActionInfo error failed")
                        handleFailInfoModel(errorString:infoModel.response.codeErrorMsg,code: infoModel.response.code)
                    default:
                        stateDatauPblished = (.progressString(generating(progress: infoModel.percent)),currentActionInfoModel)
                        processProgressChanged?(infoModel.percent*kPercentScale)
                        if stopNetwork == false {
                            kMainAfter(2.0) {
                                self.getActionInfo(action_id: action_id)
                            }
                        }
                    }
                    
                    return
                }
            }
            debugPrint("getActionInfo error nil")
            handleFailInfoModel(errorString: nil)
            
        }
    }
    
    
    func handleSuccess(infoModel:TSActionInfoModel){
        self.replaceSaveInfoModel(model: infoModel)
        self.stateDatauPblished = (.success(nil),infoModel)
        generatingProgress = 0
        self.handleGenerateSuccess()
    }
    
    func downResultUrl(infoModel:TSActionInfoModel){
        
        if retryDownloadCount > 3 {
            debugPrint("生成后下载视频失败,重新尝试超过 3 次,直接失败")
            handleFailInfoModel(errorString: nil)
            return
        }
   
//        if currentActionInfoModel.request.generatorStyle == .creatVideo {
//            let group = DispatchGroup()
//            //下载视频源
//            group.enter()
//            downloadVideo(urlString: infoModel.response.resultUrl) { url in
//                if let url = url {
//                    infoModel.response.videoDocument = url.path.documentLastURLString
//                }
//                group.leave()
//            }
//            //下载封面图
//            group.enter()
//            TSImageStoreTool.downloadImageWithProgress(urlString: infoModel.response.previewUrl) { _ in
//                group.leave()
//            }
//
//            group.notify(queue: .main){[weak self]  in
//                guard let self = self else { return }
//                if infoModel.response.videoDocument.isEmpty {
//                    debugPrint("生成后下载视频失败,重新尝试retryDownloadCount=\(retryDownloadCount)")
//                    downResultUrl(infoModel: infoModel)
//                }else{
//                    handleSuccess(infoModel: infoModel)
//                }
//            }
//
//        }else{
            downloadImage(urlString: infoModel.response.resultUrl) { [weak self] image in
                guard let self = self else { return }
                if image == nil {
                    debugPrint("生成后下载视频失败,重新尝试retryDownloadCount=\(retryDownloadCount)")
                    downResultUrl(infoModel: infoModel)
                }else{
                    handleSuccess(infoModel: infoModel)
                }
                
            }
//        }
        
        retryDownloadCount += 1
    }
    
    let generatingText:String = "Traveling to place".localized
//    func downloadVideo(urlString:String,completion:@escaping (URL?)->Void){
//        TSDownloadManager.getDownLoadVideo(urlString: urlString) { progress in
//            let progressInt = Int(progress*10.0)
//            let progressString = "Processing".localized + " " + kPercentlocalized(90 + progressInt)
//            self.stateDatauPblished = (.progressString(progressString),nil)
//            self.processProgressChanged?(0.9+Float(progress)*0.1)
//            dePrint("生成后视频下载进度: \(progress)")
//        } complete: { url, _ in
//            completion(url)
//        }
//    }
    
    func downloadImage(urlString:String,completion:@escaping (UIImage?)->Void){
        TSImageStoreTool.downloadImageWithProgress(urlString: urlString) { [weak self]  progress in
            guard let self = self else { return }
    
            let progressInt = Int(progress*10.0)
            let progressString = "Processing".localized + " " + kPercentlocalized(90 + progressInt)
            stateDatauPblished = (.progressString(progressString),currentActionInfoModel)
            self.processProgressChanged?(0.9+Float(progress)*0.1)
            dePrint("生成后图片下载进度: \(progress)")
        } completion: { image in
            completion(image)
        }
    }
    
    func generating(progress: Float) -> String {
        let progress = Float(progress)*(0.9) // 预留 10% 进度给图片下载
        //Generating 0%-100%
        var progressInt = Int(progress*100)

        if progressInt > 99 {
            progressInt = 99
        }
        
        generatingProgress = progressInt
        return generatingText + " " + kPercentlocalized(progressInt) + "..."
    }
     
    override func cancelCleanContent() {
        debugPrint("cancelCleanContent")
        stopNetwork = true
        queryRequest?.cancel()
    }
}

let kPercentScale:Float = 0.9 //下载进度的缩减比例
let kPercentScaleInt:Int = 90 //下载进度的缩减比例
func kPercentlocalized(_ num:Int)-> String{
    return String(format: "%d%%".localized, num)
//    return String(format: "%d%".localized, num)
}
