//
//  YHButlerMessageReportHandler.swift
//  galaxy
//
//  Created by alexzzw on 2024/10/29.
//  Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//

import UIKit

// 包含重试机制和详细日志
class YHButlerMessageReportHandler {
    // MARK: - Properties

    private lazy var greetings: [String] = {
        ["尊敬的客户，您好！感谢您选择银河。我是您的智能助手小鲸，时刻准备为您解答各类疑问，如果您有任何疑惑或问题，欢迎随时向我发问，我将竭诚为您服务。", "热门问题", "[银河VIP客服 from customer service is here to help you]", "[客服银河VIP客服为您服务]"]
    }()

    private lazy var patterns: [String] = {
        [
            "^尊敬的.*您好", // 匹配开头的问候语
            "我是.*智能助手", // 匹配自我介绍
            "^热门问题", // 匹配开头的固定文本
            "from customer service is here to help you]$", // 匹配结尾的固定文本
            "客服为您服务]$" // 匹配结尾的固定文本
        ]
    }()

    private static let messageReportDateKey = "butler_message_report_date"
    // QIYU_ROBOT: 用这个代表是机器人消息
    private static let robotId = "QIYU_ROBOT"

    private var messageReportKey: String? {
        guard let userId = YHLoginManager.shared.userModel?.id, userId.count > 0 else {
            return nil
        }
        return YHButlerMessageReportHandler.messageReportDateKey + "_\(userId)"
    }
    
    private lazy var getUserInfoViewModel: YHButlerServiceViewModel = YHButlerServiceViewModel()

    private let messageQueue = DispatchQueue(label: "com.galaxy.butler.messageQueue")
    private let reportQueue = DispatchQueue(label: "com.galaxy.butler.reportQueue")
    private let reportSemaphore = DispatchSemaphore(value: 1)

    private lazy var lastReportTime: Date? = {
        return getLastReportDate()
    }()

    private var nightReported = false
    // 产品定的改为5分钟
    private let oneHourInterval: TimeInterval = 300 // 3600
    private let maxRetryCount = 3
    private let retryInterval: TimeInterval = 2.0

    // MARK: - Public Methods

    func handleMessage(_ message: QYSessionInfo) {
        messageQueue.async { [weak self] in
            guard let self = self else { return }

            self.logCurrentStatus()
            let timeAllowed = self.shouldReport()
            if timeAllowed, let content = filterMessageContent(message), content.count > 0, let userId = YHLoginManager.shared.userModel?.id, userId.count > 0 {
                self.reportWithRetry(message, userId, retryCount: 0)
            } else {
                self.logSkipReason()
            }
        }
    }

    func reset() {
        messageQueue.async { [weak self] in
            guard let self = self else { return }
            self.lastReportTime = getLastReportDate()
            self.nightReported = false
            printLog("###处理器状态已重置")
        }
    }

    // MARK: - Private Methods
    
    private func getLastReportDate() -> Date? {
        guard let messageReportKey = messageReportKey, messageReportKey.count > 0 else {
            return nil
        }
        return UserDefaults.standard.value(forKey: messageReportKey) as? Date
    }

    private func shouldReport() -> Bool {
        let now = Date()
        let calendar = Calendar.current
        let hour = calendar.component(.hour, from: now)

        // 检查日期变更
        if let lastReport = lastReportTime {
            let lastReportDay = calendar.component(.day, from: lastReport)
            let currentDay = calendar.component(.day, from: now)

            if lastReportDay != currentDay {
                resetDailyStatus()
            } else {
                // 检查是否夜间已经上报了
                let lastReportHour = calendar.component(.hour, from: lastReport)
                nightReported = lastReportHour >= 0 && lastReportHour < 8
            }
        }

        // 检查时间间隔
        if let lastReport = lastReportTime {
            let timeSinceLastReport = now.timeIntervalSince(lastReport)
            if timeSinceLastReport < oneHourInterval {
                return false
            }
        }

        // 夜间规则（0-8点）
        let isNightTime = hour >= 0 && hour < 8
        if isNightTime && nightReported {
            return false
        }

        return true
    }

    private func filterMessageContent(_ message: QYSessionInfo) -> String? {
        guard let nimMessage = message.lastMessage, let from = nimMessage.from, from == YHButlerMessageReportHandler.robotId, let text = message.lastMessageText, text.count > 0 else {
            return nil
        }
        // 完全匹配
        if greetings.contains(text) {
            return nil
        }
        // 模糊匹配
        if patterns.contains(where: { pattern in
            guard let regex = try? NSRegularExpression(pattern: pattern) else { return false }
            let range = NSRange(text.startIndex..., in: text)
            return regex.firstMatch(in: text, range: range) != nil
        }) {
            return nil
        }

        return text
    }

    private func resetDailyStatus() {
        nightReported = false
    }

    private func reportWithRetry(_ message: QYSessionInfo, _ userId: String, retryCount: Int) {
        reportQueue.async { [weak self] in
            guard let self = self else { return }

            self.reportSemaphore.wait()

            guard self.shouldReport() else {
                self.reportSemaphore.signal()
                return
            }

            self.getUserInfoViewModel.sendUserIdInChat(userId, callBackBlock: { [weak self] success, _ in
                guard let self = self else { return }
                if success {
                    self.handleReportSuccess(message)
                } else if retryCount < self.maxRetryCount {
                    printLog("###上报失败，准备重试 #\(retryCount + 1)")
                    self.reportQueue.asyncAfter(deadline: .now() + self.retryInterval) {
                        self.reportWithRetry(message, userId, retryCount: retryCount + 1)
                    }
                } else {
                    printLog("###上报失败，已达到最大重试次数")
                    self.handleReportFailure(message)
                }

                self.reportSemaphore.signal()
            })
        }
    }

    private func handleReportSuccess(_ message: QYSessionInfo) {
        messageQueue.async { [weak self] in
            guard let self = self else { return }

            self.lastReportTime = Date()
            if let messageReportKey = self.messageReportKey, messageReportKey.count > 0 {
                UserDefaults.standard.set(Date(), forKey: messageReportKey)
                UserDefaults.standard.synchronize()
            }

            let hour = Calendar.current.component(.hour, from: Date())
            if hour >= 0 && hour < 8 {
                self.nightReported = true
            }
            self.logReportSuccess(message)
        }
    }

    private func handleReportFailure(_ message: QYSessionInfo) {
        printLog("###上报失败:")
        printLog("###消息ID: \(message.lastMessage?.messageId ?? "")")
        printLog("###消息内容: \(message.lastMessageText ?? "")")
    }

    private func notifyReportCompletion(_ message: QYSessionInfo, success: Bool) {
        NotificationCenter.default.post(
            name: Notification.Name("MessageReported"),
            object: nil,
            userInfo: [
                "messageId": message.lastMessage?.messageId ?? "",
                "success": success
            ]
        )
    }

    // MARK: - Logging Methods
    
    private func getTimeString(_ date: Date) -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        formatter.timeZone = TimeZone.current // 设置当前时区
        formatter.locale = Locale.current
        let localTime = formatter.string(from: date)
        return localTime
    }

    private func logCurrentStatus() {
        let now = Date()
        let localTime = getTimeString(now)

        printLog("###当前状态:")
        printLog("###时间: \(localTime)")
        if let lastReportTime = lastReportTime {
            let lastTime = getTimeString(lastReportTime)
            printLog("###上次上报: \(lastTime)")
        } else {
            printLog("###上次上报: 从未")
        }
        
        printLog("###夜间已上报: \(nightReported)")
    }

    private func logSkipReason() {
        let now = Date()
        let hour = Calendar.current.component(.hour, from: now)

        var reason = "跳过上报原因: "

        if let last = lastReportTime {
            let interval = now.timeIntervalSince(last)
            if interval < oneHourInterval {
                reason += "距离上次上报未满1小时 (间隔: \(Int(interval))秒)"
            }
        }

        if hour >= 0 && hour < 8 && nightReported {
            reason += "夜间已进行过上报"
        }

        printLog("###\(reason)")
    }

    private func logReportSuccess(_ message: QYSessionInfo) {
        printLog("###上报成功:")
        printLog("###消息ID: \(message.lastMessage?.messageId ?? "")")
        printLog("###消息内容: \(message.lastMessageText ?? "")")
        let timeString = getTimeString(Date())
        printLog("###上报时间: \(timeString)")
    }
}
