//
//  PMEmailManager.swift
//  PhoneManager
//
//  Created by edy on 2025/5/12.
//

import UIKit
import GoogleSignIn
import GoogleAPIClientForREST
import SVProgressHUD
import AppAuth


class PMEmailManager: NSObject {

    static let cloud_id = "684306808588-cl093f79dogls1a608bh8oclk3ia0rig.apps.googleusercontent.com"
    static let redirectURI = ""
    
    static let shareManager = PMEmailManager()
    
    let service = GTMSessionFetcherService()
    var loginUser:GIDGoogleUser?
    var allMessage:[EmailDetailModel] = PmEmailData()
    var messageFilter:[EmailDetailModel] = PmEmailData()
    
    var loading = false
    
    func restore() -> Void {
        GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
            if error != nil || user == nil {
                print("未找到已登录用户")
            }else{
                self.loginUser = user
            }
        }
    }
    
    func signOut(_ complate:@escaping((Bool)->Void)) -> Void {
        GIDSignIn.sharedInstance.disconnect { error in
            if error == nil {
                self.loginUser = nil
                GIDSignIn.sharedInstance.signOut()
                PMEmailManager.shareManager.messageFilter = PmEmailData()
                PMEmailManager.shareManager.allMessage = PmEmailData()
                EmailFilterManager.share.SelectEmailSet = (0..<5).map { _ in NSMutableSet() }
                complate(true)
            }else{
                complate(false)
            }
        }
    }
    
    func initOAuth(_ observer:UIViewController, _ complate:@escaping((Bool)->Void)) -> Void {
        GIDSignIn.sharedInstance.configuration = GIDConfiguration(
            clientID: PMEmailManager.cloud_id
        )
        signOut { di in
            
        }
        URLCache.shared.removeAllCachedResponses()
        let scopes = [kGTLRAuthScopeGmailModify,kGTLRAuthScopeGmailMailGoogleCom]
        GIDSignIn.sharedInstance.signIn(
            withPresenting: observer,
            hint: nil,
            additionalScopes: scopes
        ) { result, error in
            guard error == nil else { return }
            guard let user = result?.user else {
                print("登录失败: \(error?.localizedDescription ?? "")")
                complate(false)
                return
            }
            self.loginUser = user
            complate(true)
        }
    }
    
    
    // 发起登录流程
    func login(presentingVC: UIViewController, completion: @escaping (Bool, Error?) -> Void) {
        guard let issuerURL = URL(string: "https://accounts.google.com") else {
            completion(false, NSError(domain: "Auth", code: -1, userInfo: [NSLocalizedDescriptionKey: "无效的认证地址"]))
            return
        }
        
        // 发现认证配置
        OIDAuthorizationService.discoverConfiguration(forIssuer: issuerURL) { [weak self] config, error in
            guard let self = self, let config = config else {
                completion(false, error ?? NSError(domain: "Auth", code: -2, userInfo: [NSLocalizedDescriptionKey: "配置获取失败"]))
                return
            }
            
            // 构建认证请求（解决code -15的关键参数）
            let request = OIDAuthorizationRequest(
                configuration: config,
                clientId: PMEmailManager.cloud_id,
                scopes: [OIDScopeOpenID, OIDScopeEmail, "https://www.googleapis.com/auth/gmail.readonly"],
                redirectURL: URL(string: PMEmailManager.redirectURI)!,
                responseType: OIDResponseTypeCode,
                additionalParameters: [
                    "prompt": "consent", // 强制获取新令牌，解决缓存过期问题
                    "max_age": "0" // 不接受过期的会话
                ]
            )
            
            URLCache.shared.removeAllCachedResponses()
            
            // 发起认证
            OIDAuthState.authState(byPresenting: request, presenting: presentingVC) { authState, error in
                if let error = error {
                    completion(false, error)
                    return
                }
                
                guard let authState = authState else {
                    completion(false, NSError(domain: "Auth", code: -3, userInfo: [NSLocalizedDescriptionKey: "认证状态为空"]))
                    return
                }
                
//                // 验证新获取的令牌
//                self.validateToken(authState: authState) { valid in
//                    if valid {
//                        self.authState = authState
//                        completion(true, nil)
//                    } else {
//                        completion(false, NSError(domain: "Auth", code: -15, userInfo: [NSLocalizedDescriptionKey: "令牌验证失败"]))
//                    }
//                }
            }
        }
    }
    

    func fetchEmails(_ complate:@escaping(()->Void)) {
        if loading {
            return
        }
        loading = true
        let service = GTLRGmailService()
        messageFilter = PmEmailData()
        service.authorizer = self.loginUser?.fetcherAuthorizer
        service.shouldFetchNextPages = true
        let query = GTLRGmailQuery_UsersMessagesList.query(withUserId: self.loginUser?.userID ?? "me")
        query.includeSpamTrash = true
        query.labelIds = ["INBOX"]
        
        service.executeQuery(query) { ticket, result, error in
            guard let list = result as? GTLRGmail_ListMessagesResponse else {
                self.loading = false
                Alert("error","Request timed out, please try again")
                complate()
                return
            }
            DispatchQueue.global().async {
                var num = 0
                list.messages?.forEach { Omsg in
                    self.fetchEmailDetails(Omsg.identifier ?? "" ,message: Omsg) {
                        num += 1
                        if list.messages?.count ?? 0 == num {
                            emailSort()
                            DispatchQueue.main.async {
                                self.loading = false
                                complate()
                            }
                        }
                    }
                }
            }
        }
    }
    
    func fetchEmailDetails(_ messageID:String ,message:GTLRGmail_Message ,_ complate:@escaping(()->Void) ) {
        let service = GTLRGmailService()
        service.authorizer = self.loginUser?.fetcherAuthorizer
        let query = GTLRGmailQuery_UsersMessagesGet.query(
            withUserId: self.loginUser?.userID ?? "me",
            identifier: messageID // 替换具体邮件ID
        )
        query.format = kGTLRGmailFormatFull // 获取完整邮件内容
        service.executeQuery(query) { trick, result, error in
            guard let message = result as? GTLRGmail_Message else {
                complate()
                return
            }
            _ = self.Analysis(message: message)
            complate()
        }
    }
    
    // MARK: - 解析邮件正文
    private func parseMessageBody(_ message: GTLRGmail_Message) -> (plainText: String?, html: String?) {
        guard let payload = message.payload else { return (nil, nil) }
        var plainText: String?, html: String?
        func traverseParts(_ part: GTLRGmail_MessagePart) {
            if let mimeType = part.mimeType {
                switch mimeType {
                case "text/plain":
                    plainText = decodeBodyData(part.body?.data)
                case "text/html":
                    html = decodeBodyData(part.body?.data)
                case "multipart/alternative", "multipart/mixed", "multipart/related":
                    part.parts?.forEach(traverseParts)
                default: break
                }
            }
        }
        traverseParts(payload)
        return (plainText, html)
    }
    
    /** 发件人、主题、时间 */
    private func extractHeaders(from message: GTLRGmail_Message) -> (from: String?, subject: String?, date: String? ,to:String?) {
        guard let headers = message.payload?.headers else { return (nil, nil, nil, nil) }
        var from: String?
        var subject: String?
        var date: String?
        var to:String?
        for header in headers {
            switch header.name?.lowercased() {
            case "from":
                from = header.value
            case "subject":
                subject = header.value
            case "date":
                date = header.value
            case "to":
                to = header.value
            default:
                break
            }
        }
        return (from, subject, date, to)
    }
    
    // MARK: - 解析附件
    private func parseAttachments(_ message: GTLRGmail_Message) -> [(filename: String, data: Data)] {
        var attachments = [(String, Data)]()
        func traverseParts(_ part: GTLRGmail_MessagePart) {
            if let filename = part.filename, !filename.isEmpty,
               let dataStr = part.body?.data,
               let data = Data(base64Encoded: dataStr) {
                attachments.append((filename, data))
            }
            part.parts?.forEach(traverseParts)
        }
        
        if let payload = message.payload {
            traverseParts(payload)
        }
        return attachments
    }
    
    // MARK: - 标记为已读
    func markMessageAsRead( messageId: String, completion: @escaping (Bool, Error?) -> Void) {
        let service = GTLRGmailService()
        service.authorizer = self.loginUser?.fetcherAuthorizer
        // 创建修改请求
        let modifyRequest = GTLRGmail_ModifyMessageRequest()
        modifyRequest.removeLabelIds = ["UNREAD"] // 固定标签ID
        // 构建查询
        let query = GTLRGmailQuery_UsersMessagesModify.query(
            withObject: modifyRequest,
            userId: self.loginUser?.userID ?? "me",
            identifier: messageId
        )
        // 执行请求
        service.executeQuery(query) { (ticket, response, error) in
            if let error = error {
                print("标记为已读失败: \(error.localizedDescription)")
                completion(false, error)
                return
            }
            // 验证是否成功
            if let modifiedMessage = response as? GTLRGmail_Message,
               modifiedMessage.labelIds?.contains("UNREAD") == false {
                print("标记成功")
                completion(true, nil)
            } else {
                let error = NSError(domain: "GmailError", code: -1, userInfo: [NSLocalizedDescriptionKey: "未知错误"])
                completion(false, error)
            }
        }
    }

    // MARK: - 批量删除邮件
    func deleteEmail(_ indexPath:Int = -1, _ complate:@escaping((Bool)->Void)) -> Void {
        let messageID = NSMutableSet()
        if indexPath < 0 {
            for i in 0..<5 {
                for row in EmailFilterManager.share.SelectEmailSet[i].allObjects {
                    guard let rowInt = row as? Int else { return }
                    guard let msgId = PMEmailManager.shareManager.allMessage[i].child[rowInt].messageId else { return }
                    messageID.add(msgId)
                }
            }
        }else{
            for row in EmailFilterManager.share.SelectEmailSet[indexPath].allObjects {
                guard let rowInt = row as? Int else { return }
                guard let msgId = PMEmailManager.shareManager.allMessage[indexPath].child[rowInt].messageId else { return }
                messageID.add(msgId)
            }
        }
        
        if  let ids = messageID.allObjects as? [String],
                ids.count > 0 {
            let service = GTLRGmailService()
            service.authorizer = self.loginUser?.fetcherAuthorizer
            
            let batchDeleteRequest = GTLRGmail_BatchDeleteMessagesRequest()
            batchDeleteRequest.ids = ids
            // 2. 构建查询
            let query = GTLRGmailQuery_UsersMessagesBatchDelete.query(
                withObject: batchDeleteRequest,
                userId: self.loginUser?.userID ?? "me"
            )
            // 3. 执行请求
            service.executeQuery(query) { ticker, results, error in
                if let error = error {
                    complate(false)
                }else{
                    self.deletaLocal(all: indexPath , messageID)
                    complate(true)
                }
            }
        }
    }
    
    private func deletaLocal(all:Int , _ deletes:NSMutableSet)->Void {
        if all < 0 {
            for i in 0..<5 {
                PMEmailManager.shareManager.messageFilter[i].child = PMEmailManager.shareManager.messageFilter[i].child.filter({ msg in
                    return !deletes.contains(msg.messageId ?? "")
                })
            }
            EmailFilterManager.share.SelectEmailSet = (0..<5).map { _ in NSMutableSet() }
        }else{
            PMEmailManager.shareManager.messageFilter[all].child = PMEmailManager.shareManager.messageFilter[all].child.filter({ msg in
                return !deletes.contains(msg.messageId ?? "")
            })
            EmailFilterManager.share.SelectEmailSet[all] = NSMutableSet()
        }
        emailSort()
//        PMEmailManager.shareManager.allMessage = PMEmailManager.shareManager.messageFilter
    }
    
    func Analysis(message:GTLRGmail_Message) -> EmailMessageModel {
        var email = EmailMessageModel()
        email.messageId = message.identifier
        email.snippet = message.snippet
        email.labelids = message.labelIds
        
        var payload = EmailMessagepayLoadModel()
        let headers = self.extractHeaders(from: message)
        payload.headers = EmailMessageHeadersModel(from: headers.from,subject: headers.subject,date: headers.date, to: headers.to)
        
        let plaint = self.parseMessageBody(message)
        payload.body.plainText = plaint.plainText
        payload.body.html = plaint.html
        email.payload = payload
        
        let labels = ["CATEGORY_SOCIAL","CATEGORY_PROMOTIONS","CATEGORY_UPDATES","CATEGORY_FORUMS","SPAM"]
        let sets:NSMutableSet = NSMutableSet(array: message.labelIds ?? [])
        for l in labels {
            if sets.contains(l) {
                if l == labels.first {
                    self.messageFilter[0].child.append(email)
                }else if l == labels[1] {
                    self.messageFilter[1].child.append(email)
                }else if l == labels[2] {
                    self.messageFilter[2].child.append(email)
                }else if l == labels[3] {
                    self.messageFilter[3].child.append(email)
                }else if l == labels[4] {
                    self.messageFilter[4].child.append(email)
                }
            }
        }
        return email
    }
    
    
    /** 解析base 64 */
    private func decodeBody(_ data: String?) -> String {
        guard let encodedData = data?.replacingOccurrences(of: "-", with: "+")
            .replacingOccurrences(of: "_", with: "/"),
              let decodedData = Data(base64Encoded: encodedData, options: .ignoreUnknownCharacters)
        else { return "" }
        return String(data: decodedData, encoding: .utf8) ?? ""
    }
    
    // MARK: - Base64解码（处理URL-safe编码）
    private func decodeBodyData(_ base64String: String?) -> String? {
        guard var dataStr = base64String?
            .replacingOccurrences(of: "-", with: "+")
            .replacingOccurrences(of: "_", with: "/") else {
            return nil
        }
        // 补齐Base64填充字符
        let padding = dataStr.count % 4
        if padding > 0 {
            dataStr += String(repeating: "=", count: 4 - padding)
        }
        guard let data = Data(base64Encoded: dataStr) else { return nil }
        return String(data: data, encoding: .utf8)
    }
}

fileprivate func EMfilter() -> Void {
    
    var date:Date?
    switch EmailFilterManager.share.FilterSet.date {
    case 1:
        date = Date().operation(day: -7)
    case 2:
        date = Date().operation(month: -1)
    case 3:
        date = Date().operation(year: -1)
    default:
        break
    }
    var filtrate = PMEmailManager.shareManager.messageFilter
    for i in 0..<5 {
        filtrate[i].child = filtrate[i].child.filter({ msg in
            var isTime = true
            var isRead = true
            var keyword = true
            if date != nil {            // 时间
                let tm1 = msg.payload?.headers?.date?.EmailDateFromat().timeIntervalSince1970 ?? 0
                let tm2 = date?.timeIntervalSince1970 ?? Date().timeIntervalSince1970
                isTime = tm1 < tm2
            }
            let labels = msg.labelids ?? []
            if EmailFilterManager.share.FilterSet.read && EmailFilterManager.share.FilterSet.unread {
                isRead = true
            }else if EmailFilterManager.share.FilterSet.read {
                isRead = !labels.contains("UNREAD")
            }else{
                isRead = labels.contains("UNREAD")
            }
            if EmailFilterManager.share.FilterSet.keyword { // 关键字
                for key in EmailFilterManager.share.keyword {
                    let keyw = msg.payload?.headers?.subject?.contains(key) ?? true
                    if keyw == true {
                        keyword = false
                        break
                    }
                }
            }
            return isTime && isRead && keyword
        })
    }
    PMEmailManager.shareManager.allMessage = filtrate
    NotificationCenter.default.post(name: messageUpdate, object: nil)
    Print("邮件加载成功")
}

let messageUpdate = NSNotification.Name("emailUpdate")

public func emailSort() -> Void {
    
    for i in 0..<5 {  // 时间排序
        PMEmailManager.shareManager.messageFilter[i].child = PMEmailManager.shareManager.messageFilter[i].child.sorted { email, email1 in
            let t1 = email.payload?.headers?.date?.EmailDateFromat().timeIntervalSince1970 ?? 0
            let t2 = email1.payload?.headers?.date?.EmailDateFromat().timeIntervalSince1970 ?? 0
            return t1 > t2
        }
    }
    EMfilter()
    
}
