//
//  YHResignMaterialViewModel.swift
//  galaxy
//
//  Created by edy on 2024/9/10.
//  Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//

import UIKit

class YHResignMaterialInfo {
    
    var title: String = ""
    var materials: [YHMaterialModel] = []
    // 是否展开 默认展开
    var isUnfold: Bool = true
    
    init(title: String, materials: [YHMaterialModel]) {
        self.title = title
        self.materials = materials
    }
}

class YHResignMaterialGroup {
    
    var status: YHMaterialStatus = .all
    // 工作资料
    var works: [YHMaterialModel] = []
    // 生活资料
    var lifes: [YHMaterialModel] = []
    // 证件资料
    var cers: [YHMaterialModel] = []

    func getTotalCount() -> Int {
        return works.count + lifes.count + cers.count
    }
    
    func clear() {
        works.removeAll()
        lifes.removeAll()
        cers.removeAll()
    }
    
    func getDataArr() -> [YHResignMaterialInfo] {
        var arr: [YHResignMaterialInfo] = []
        if works.count > 0 {
            let work = YHResignMaterialInfo(title: "工作资料", materials: works)
            arr.append(work)
        }
        if lifes.count > 0 {
            let life = YHResignMaterialInfo(title: "生活资料", materials: lifes)
            arr.append(life)
        }
        if cers.count > 0 {
            let cer = YHResignMaterialInfo(title: "证件资料", materials: cers)
            arr.append(cer)
        }
        return arr
    }
}

class YHResignMaterialViewModel: YHBaseViewModel {
    // 全部
    var allGroup: YHResignMaterialGroup = YHResignMaterialGroup()
    // 待上传
    var preuploadGroup: YHResignMaterialGroup = YHResignMaterialGroup()
    // 已驳回
    var rejectedGroup: YHResignMaterialGroup = YHResignMaterialGroup()
    // 审核中
    var reviewGroup: YHResignMaterialGroup = YHResignMaterialGroup()
    // 已完成
    var finishGroup: YHResignMaterialGroup = YHResignMaterialGroup()
    
    // 某个具体资料详情
    var materialDeal: YHMaterialModel = YHMaterialModel()
    
    // 某个具体资料模板
    var templateDeail: YHResignTemplateDetail = YHResignTemplateDetail()
    
    func clear() {
        self.allGroup.clear()
        self.preuploadGroup.clear()
        self.rejectedGroup.clear()
        self.reviewGroup.clear()
        self.finishGroup.clear()
    }
    
    func getMaterialList(param: [String: Any], callback: ((_ success: Bool, _ error: YHErrorModel?) -> Void)?) {
        
        let strUrl = YHBaseUrlManager.shared.curURL() + YHAllApiName.ResignMaterial.resignMaterialList
        _ = YHNetRequest.getRequest(url: strUrl, params: param) { [weak self] json, _ in
            // 1. json字符串 转 对象
            guard let self = self else { return }
            printLog("model 是 ==> \(json)")
            
            if json.code == 200 {
                
                guard let dic = json.data?.peel as? [String: Any], let resultModel = YHMaterialListModel.deserialize(from: dic) else {
                    let err = YHErrorModel(errorCode: YHErrorCode.dictParseError.rawValue, errorMsg: YHErrorCode.dictParseError.description())
                    self.clear()
                    callback?(false, err)
                    return
                }
                let materials = resultModel.material
                self.allGroup = self.generateGroup(status: .all, materials: materials)
                self.preuploadGroup = self.generateGroup(status: .preUpload, materials: materials)
                self.rejectedGroup = self.generateGroup(status: .rejected, materials: materials)
                self.reviewGroup = self.generateGroup(status: .review, materials: materials)
                self.finishGroup = self.generateGroup(status: .completed, materials: materials)
                callback?(true, nil)
                
            } else {
                
                let err = YHErrorModel(errorCode: Int32(json.code), errorMsg: json.msg.isEmpty ? "" : json.msg)
                self.clear()
                callback?(false, err)
            }
            
        } failBlock: { err in
            self.clear()
            callback?(false, err)
        }
    }
    
    func generateGroup(status: YHMaterialStatus, materials: [YHMaterialModel]) -> YHResignMaterialGroup {
        let group = YHResignMaterialGroup()
        group.status = status
        
        for material in materials {
            let condition: Bool = (status == .all ? true : material.status == status.rawValue)
            if condition {
                if material.mtype == YHMaterialType.work.rawValue {
                    group.works.append(material)
                }
                if material.mtype == YHMaterialType.live.rawValue {
                    group.lifes.append(material)

                }
                if material.mtype == YHMaterialType.cer.rawValue {
                    group.cers.append(material)
                }
            }
        }
        return group
    }
    
    func getMaterialDeal(orderId: Int, id: Int, materialId: Int, callback: ((_ success: Bool, _ error: YHErrorModel?) -> Void)?) {
        
        let params = ["order_id": orderId,
                      "id": id,
                      "material_id": materialId]
        let strUrl = YHBaseUrlManager.shared.curURL() + YHAllApiName.ResignMaterial.resignMaterialList
        _ = YHNetRequest.getRequest(url: strUrl, params: params) { [weak self] json, _ in
            // 1. json字符串 转 对象
            guard let self = self else { return }
            printLog("model 是 ==> \(json)")
            
            if json.code == 200 {
                guard let dic = json.data?.peel as? [String: Any], let resultModel = YHMaterialListModel.deserialize(from: dic) else {
                    let err = YHErrorModel(errorCode: YHErrorCode.dictParseError.rawValue, errorMsg: YHErrorCode.dictParseError.description())
                    callback?(false, err)
                    return
                }
                if let first = resultModel.material.first {
                    self.materialDeal = first
                }
                callback?(true, nil)
                
            } else {
                let err = YHErrorModel(errorCode: Int32(json.code), errorMsg: json.msg.isEmpty ? "" : json.msg)
                callback?(false, err)
            }
            
        } failBlock: { err in
            callback?(false, err)
        }
    }
    
    func getTemplateInfo(templateId: Int, callback: ((_ success: Bool, _ error: YHErrorModel?) -> Void)?) {
        
        let params = ["template_id": templateId]
        let strUrl = YHBaseUrlManager.shared.curURL() + YHAllApiName.ResignMaterial.resginTemplateDetail
        
        _ = YHNetRequest.getRequest(url: strUrl, params: params) { [weak self] json, _ in
            // 1. json字符串 转 对象
            guard let self = self else { return }
            printLog("model 是 ==> \(json)")
            
            if json.code == 200 {
                guard let dic = json.data?.peel as? [String: Any], let resultModel = YHResignTemplateDetail.deserialize(from: dic) else {
                    let err = YHErrorModel(errorCode: YHErrorCode.dictParseError.rawValue, errorMsg: YHErrorCode.dictParseError.description())
                    callback?(false, err)
                    return
                }
                self.templateDeail = resultModel
                callback?(true, nil)
                
            } else {
                let err = YHErrorModel(errorCode: Int32(json.code), errorMsg: json.msg.isEmpty ? "" : json.msg)
                callback?(false, err)
            }
            
        } failBlock: { err in
            callback?(false, err)
        }
    }
    
    // 添加/删除/重命名 资料
    func updateMaterials(material: YHMaterialModel, addInfoArr: [YHMaterialModelItemModel], callback: ((_ success: Bool, _ error: YHErrorModel?) -> Void)?) {
        
        let strUrl = YHBaseUrlManager.shared.curURL() + YHAllApiName.ResignMaterial.uploadMaterials
        var params: [String: Any] = [
            "material_id": "\(material.id)",
            "template_id": "\(material.template_id)",
            "status": material.status,
            "audit_remark": material.audit_remark
        ]
        
        var info: [[String: Any]] = []
        
        for item in material.info {
            if let dict = item.toDictionary() {
                info.append(dict)
            }
        }
        
        for item in addInfoArr {
            if let dict = item.toDictionary() {
                info.append(dict)
            }
        }
        params["info"] = info
        
        _ = YHNetRequest.postRequest(url: strUrl, params: params) { [weak self] json, _ in
            // 1. json字符串 转 对象
            guard let self = self else { return }
            printLog("model 是 ==> \(json)")
            
            if json.code == 200 {
                guard let isSuccess = json.data?.peel as? Bool else {
                    let err = YHErrorModel(errorCode: YHErrorCode.dictParseError.rawValue, errorMsg: YHErrorCode.dictParseError.description())
                    callback?(false, err)
                    return
                }
                callback?(isSuccess, nil)
                
            } else {
                let err = YHErrorModel(errorCode: Int32(json.code), errorMsg: json.msg.isEmpty ? "" : json.msg)
                callback?(false, err)
            }
            
        } failBlock: { err in
            callback?(false, err)
        }
    }
    
    // OSS上传资料后再进行服务器后台更新
    func uploadFilesWithMaterial(material: YHMaterialModel, fileUrl: URL, callback: (() -> Void)?) {
        
        if let fileData = try? Data(contentsOf: fileUrl) {
            // 将文件数据上传到服务器
            let size = String(format: "%.2fM", Double(fileData.count)/(1024.0 * 1024.0))
            print("\(size)")
            // 先OSS上传得到URL
            YHHUD.show(.progress(message: "上传中..."))
            self.uploadFile(fileUrl.absoluteString) {
                [weak self] successUrl, error in
                guard let self = self else { return }
                
                YHHUD.hide()
                
                // 再调用业务接口
                if let successUrl = successUrl, !successUrl.isEmpty {
                    var fileName = fileUrl.absoluteString.lastPathComponent
                    // 解决中文名称乱码问题
                    if let decodedFileName = fileName.removingPercentEncoding {
                        fileName = decodedFileName
                    }
                    
                    let model = YHMaterialModelItemModel()
                    model.url = successUrl
                    model.name = fileName
                    model.naming = fileName
                    
                    let dateFormatter = DateFormatter()
                    dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss"
                    let dateString = dateFormatter.string(from: Date())
                    model.updated_at = dateString
                    
                    YHHUD.show(.progress(message: "上传中..."))
                    self.updateMaterials(material: material, addInfoArr: [model]) {
                        success, error in
                        YHHUD.hide()
                        if success {
                            YHHUD.flash(message: "上传成功")
                        } else {
                            var msg = "上传失败"
                            if let errorMsg = error?.errorMsg, !errorMsg.isEmpty {
                                msg = errorMsg
                            }
                            YHHUD.flash(message: msg)
                        }
                        callback?()
                    }
                    return
                }
                var msg = "上传图片失败"
                if let errorMsg = error?.errorMsg, !errorMsg.isEmpty {
                    msg = errorMsg
                }
                YHHUD.flash(message: msg)

            }
        } else {
            YHHUD.flash(message: "识别文件失败")
        }
    }
    
    func uploadImageArr(_ targetImgArr: [YHSelectImageItem], material: YHMaterialModel, successBlock: (() -> Void)?) {
        
        let ossGroup = DispatchGroup()
        var ossArr: [YHMaterialModelItemModel] = []

        YHHUD.show(.progress(message: "上传中..."))
        // 先将所有图片组上传到OSS
        for item in targetImgArr {
            if let image = item.data {
                ossGroup.enter()
                uploadImage(image, imageName: item.name) {
                    success, urlModel in
                    if success, let model = urlModel {
                        ossArr.append(model)
                    }
                    ossGroup.leave()
                }
            }
        }
        
        // 再将OSS上传信息组上传到服务器
        ossGroup.notify(queue: .main) {
            if ossArr.count <= 0 {
                YHHUD.hide()
                YHHUD.flash(message: "上传失败")
                return
            }
            
            self.updateMaterials(material: material, addInfoArr: ossArr) {
                [weak self] success, _ in
                guard let self = self else { return }

                YHHUD.hide()
                if  success {
                    if ossArr.count == targetImgArr.count {
                        YHHUD.flash(message: "上传成功")
                    } else {
                        YHHUD.flash(message: "\(ossArr.count)张照片上传成功\n\(targetImgArr.count-ossArr.count)张照片上传失败")
                    }
                    successBlock?()
                    
                } else {
                    YHHUD.flash(message: "上传失败")
                }
            }
        }
    }
    
    func uploadImage(_ img: UIImage, imageName: String, callBack: ((Bool, YHMaterialModelItemModel?) -> Void)?) {
        
        // 先OSS上传得到URL
        self.uploadImage(img) {
            [weak self] url, _ in
            guard let self = self else { return }
            if let url = url, !url.isEmpty {
                var suffix = "jpg"
                let suffixName = url.pathExtension.lowercased()
                if !suffixName.isEmpty {
                    suffix = suffixName
                }
                
                // 再调用业务接口
                let model = YHMaterialModelItemModel()
                var imgName = imageName
                if let fileURL = URL(string: imageName) {
                    imgName = fileURL.deletingPathExtension().lastPathComponent + "." + suffix
                }
            
                model.name = imgName
                model.naming = imgName
                model.url = url
                
                let dateFormatter = DateFormatter()
                dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss"
                let dateString = dateFormatter.string(from: Date())
                model.updated_at = dateString
                callBack?(true, model)
            } else {
                callBack?(false, nil)
            }
        }
    }
}
