import sys
from PyQt5.QtCore import Qt, pyqtSignal, QObject
from PyQt5.QtGui import QFont, QPalette, QColor
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
                             QHBoxLayout, QLabel, QPushButton, QLineEdit,
                             QTextEdit, QFrame, QDialog, QDialogButtonBox, QComboBox,
                             QSystemTrayIcon, QMenu, QAction, QMessageBox, QGraphicsDropShadowEffect)
from PyQt5.QtCore import QPropertyAnimation, QEasingCurve, QRect, QTimer, pyqtProperty
from PyQt5.QtGui import QColor
import config
from WebSocket.backend_singleton import get_websocket_manager
from windows_taskbar_fix import setup_windows_taskbar_icon
import os


# ===================== 文件日志系统 - 生产环境启用 =====================
# 重定向所有输出到文件，确保有日志记录
from exe_file_logger import setup_file_logging, log_to_file  # 开发环境启用

setup_file_logging()  # 开发环境启用自动日志功能
print("文件日志系统已在main.py中初始化")  # 开发环境启用


# 新增: 版本更新信号类（用于线程安全的 GUI 通知）
class UpdateSignals(QObject):
    """版本更新信号"""
    update_available = pyqtSignal(str, str)  # (latest_version, download_url)


# 新增: 断开连接信号类（用于线程安全的断开提示）
class DisconnectSignals(QObject):
    """断开连接信号"""
    disconnected = pyqtSignal(str)  # (disconnect_message)


# 新增: 用户名密码输入对话框类
class LoginWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.jd_worker = None
        self.progress_dialog = None
        self.douyin_worker = None
        self.qian_niu_worker = None
        self.pdd_worker = None

        # 重复执行防护
        self.last_login_time = 0
        self.login_cooldown = 2  # 登录冷却时间（秒）

        # 平台连接状态管理
        self.connected_platforms = []
        self.status_timer = None
        self.last_platform_connect_time = 0  # 记录最后一次平台连接时间

        # 日志管理相关变量已删除

        # 创建版本更新信号对象（线程安全）
        self.update_signals = UpdateSignals()
        self.update_signals.update_available.connect(self._show_update_dialog)

        # 创建断开连接信号对象（线程安全）
        self.disconnect_signals = DisconnectSignals()
        self.disconnect_signals.disconnected.connect(self._show_disconnect_dialog)

        # 横幅相关
        self.promo_banner = None
        self.banner_shadow = None  # 阴影效果引用

        self.initUI()

        # 延迟设置版本检查器，确保WebSocket连接已建立
        QTimer.singleShot(5000, self.setup_version_checker)

    def initUI(self):
        # 设置窗口基本属性
        self.setWindowTitle(f'AI客服智能助手 v{config.APP_VERSION}')
        # 只设置宽度，高度自适应内容
        self.setFixedWidth(450)  # 固定宽度
        # 不设置固定高度，让窗口根据内容自适应

        # 窗口图标将由统一的任务栏修复模块设置，这里只做备用检查
        print("[INFO] 窗口图标将由统一模块设置")

        # 创建中央widget
        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        # 创建主布局（最小化间距）
        main_layout = QVBoxLayout()
        main_layout.setSpacing(8)  # 最小间距
        main_layout.setContentsMargins(25, 12, 25, 12)  # 最小边距
        central_widget.setLayout(main_layout)

        # 添加标题和副标题
        title_label = QLabel('AI客服智能助手')
        title_label.setObjectName("title")
        title_label.setAlignment(Qt.AlignCenter)
        title_label.setFont(QFont('Microsoft YaHei', 16, QFont.Bold))  # 稍微减小字体
        title_label.setStyleSheet("color: #2c3e50; margin-bottom: 2px;")
        main_layout.addWidget(title_label)

        # 添加副标题说明
        subtitle_label = QLabel('智能连接多平台客服，提供AI自动回复服务')
        subtitle_label.setObjectName("subtitle")
        subtitle_label.setAlignment(Qt.AlignCenter)
        subtitle_label.setFont(QFont('Microsoft YaHei', 9))
        subtitle_label.setStyleSheet("color: #7f8c8d; margin-bottom: 5px;")
        main_layout.addWidget(subtitle_label)

        # 创建令牌输入区域（移除额外间距）
        token_layout = QVBoxLayout()
        token_layout.setSpacing(6)  # 最小间距

        token_label = QLabel('访问令牌')
        token_label.setFont(QFont('Microsoft YaHei', 11, QFont.Bold))  # 减小字体
        token_label.setStyleSheet("color: #34495e;")

        self.token_input = QLineEdit()
        self.token_input.setPlaceholderText('请输入您的访问令牌以连接服务')
        self.token_input.setEchoMode(QLineEdit.Password)
        self.token_input.setFont(QFont('Microsoft YaHei', 10))
        # noinspection PyUnresolvedReferences
        self.token_input.returnPressed.connect(self.login)  # 表示回车提交
        self.token_input.setMinimumHeight(34)  # 最小输入框高度
        # 预填已保存的令牌（如果存在）
        try:
            from config import get_saved_token
            saved = get_saved_token()
            if saved:
                self.token_input.setText(saved)
        except Exception:
            pass

        token_layout.addWidget(token_label)
        token_layout.addWidget(self.token_input)
        main_layout.addLayout(token_layout)

        # 创建连接按钮
        self.login_btn = QPushButton('连接服务')
        self.login_btn.setFont(QFont('Microsoft YaHei', 11, QFont.Bold))
        self.login_btn.setMinimumHeight(36)  # 最小按钮高度
        self.login_btn.clicked.connect(self.login)  # 表示点击提交
        main_layout.addWidget(self.login_btn)

        # 添加连接状态提示
        self.status_label = QLabel('等待连接...')
        self.status_label.setObjectName("status")
        self.status_label.setAlignment(Qt.AlignCenter)
        self.status_label.setFont(QFont('Microsoft YaHei', 9))
        self.status_label.setStyleSheet("color: #95a5a6; margin-top: 2px;")
        main_layout.addWidget(self.status_label)

        # 添加最小间距（为横幅留出位置）
        main_layout.addSpacing(8)

        # ============ 添加宣传横幅 ============
        self.create_promo_banner(main_layout)

        # 日志框已永久删除，只使用终端输出
        self.log_display = None

        # 应用现代化样式
        self.apply_modern_styles()

        # 添加视觉效果
        self.add_visual_effects()

        # 初始化系统托盘
        self.init_system_tray()

        # 系统初始化日志输出到终端
        print("[INFO] 系统初始化完成")
        
        # 让窗口自适应内容高度（最小化）
        self.adjustSize()
        print("[INFO] 窗口已自适应内容大小")

    def create_promo_banner(self, layout):
        """创建宣传横幅（使用图片，带悬停动画效果）"""
        try:
            # 创建横幅容器
            banner_frame = QFrame()
            banner_frame.setObjectName("promoBanner")
            banner_frame.setCursor(Qt.PointingHandCursor)  # 鼠标变手型
            
            # 保存横幅引用，用于动画
            self.promo_banner = banner_frame
            
            # 使用图片标签
            banner_image = QLabel()
            banner_image.setObjectName("bannerImage")
            
            # 加载横幅图片
            from windows_taskbar_fix import get_resource_path
            image_path = get_resource_path("static/hengfu.jpg")
            
            if os.path.exists(image_path):
                from PyQt5.QtGui import QPixmap
                pixmap = QPixmap(image_path)
                
                # 设置固定的横幅尺寸
                target_width = 400  # 固定宽度
                target_height = 70  # 固定高度（调整为70px，更紧凑）
                
                # 缩放图片以适应目标尺寸
                scaled_pixmap = pixmap.scaled(
                    target_width, 
                    target_height,
                    Qt.IgnoreAspectRatio,  # 忽略宽高比，拉伸填充
                    Qt.SmoothTransformation  # 平滑缩放，提高图片质量
                )
                
                # 设置图片
                banner_image.setPixmap(scaled_pixmap)
                banner_image.setScaledContents(False)
                
                banner_frame.setFixedHeight(target_height)
                banner_image.setFixedSize(target_width, target_height)
                
                # 🔧 使用CSS圆角来处理边角（更简单稳定）
                banner_image.setStyleSheet("""
                    QLabel#bannerImage {
                        border-radius: 12px;
                        background-color: transparent;
                    }
                """)
                
                print(f"[INFO] 横幅图片已加载: {image_path}, 尺寸: {target_width}x{target_height}")
            else:
                # 图片不存在时的备用方案
                banner_image.setText("🌟 限时优惠活动 - 点击了解详情 →")
                banner_image.setAlignment(Qt.AlignCenter)
                banner_image.setStyleSheet("""
                    background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
                        stop:0 #667eea, stop:1 #764ba2);
                    color: white;
                    font-size: 12px;
                    font-weight: bold;
                    border-radius: 12px;
                    padding: 15px;
                """)
                banner_frame.setFixedHeight(60)
                print(f"[WARNING] 横幅图片未找到: {image_path}，使用备用样式")
            
            # 创建布局
            banner_layout = QHBoxLayout()
            banner_layout.setContentsMargins(0, 0, 0, 0)
            banner_layout.setSpacing(0)
            banner_frame.setLayout(banner_layout)
            banner_layout.addWidget(banner_image)
            
            # 设置圆角和边框
            banner_frame.setStyleSheet("""
                QFrame#promoBanner {
                    border-radius: 12px;
                    background: transparent;
                }
            """)
            
            # 初始阴影效果
            self.banner_shadow = QGraphicsDropShadowEffect()
            self.banner_shadow.setBlurRadius(15)
            self.banner_shadow.setXOffset(0)
            self.banner_shadow.setYOffset(3)
            self.banner_shadow.setColor(QColor(0, 0, 0, 60))
            banner_frame.setGraphicsEffect(self.banner_shadow)
            
            # 点击事件 - 跳转官网
            def open_official_website():
                try:
                    import webbrowser
                    official_url = "https://shuidrop.com/"
                    webbrowser.open(official_url)
                    self.add_log(f"已打开官网: {official_url}", "INFO")
                except Exception as e:
                    self.add_log(f"打开官网失败: {e}", "ERROR")
            
            banner_frame.mousePressEvent = lambda event: open_official_website()
            
            # 🎯 添加鼠标悬停事件（动态效果）
            def on_enter(event):
                """鼠标进入时的动画效果"""
                try:
                    # 增强阴影效果
                    self.banner_shadow.setBlurRadius(25)
                    self.banner_shadow.setYOffset(5)
                    self.banner_shadow.setColor(QColor(0, 0, 0, 100))
                    
                    # 轻微放大动画
                    animation = QPropertyAnimation(banner_frame, b"geometry")
                    original_rect = banner_frame.geometry()
                    
                    expanded_rect = QRect(
                        original_rect.x() - 3,
                        original_rect.y() - 2,
                        original_rect.width() + 6,
                        original_rect.height() + 4
                    )
                    
                    animation.setDuration(200)
                    animation.setStartValue(original_rect)
                    animation.setEndValue(expanded_rect)
                    animation.setEasingCurve(QEasingCurve.OutCubic)
                    animation.start()
                    
                    # 保存动画引用避免被垃圾回收
                    banner_frame.hover_animation = animation
                    
                except Exception as e:
                    print(f"[DEBUG] 悬停动画错误: {e}")
            
            def on_leave(event):
                """鼠标离开时的动画效果"""
                try:
                    # 恢复阴影效果
                    self.banner_shadow.setBlurRadius(15)
                    self.banner_shadow.setYOffset(3)
                    self.banner_shadow.setColor(QColor(0, 0, 0, 60))
                    
                    # 恢复原始大小
                    animation = QPropertyAnimation(banner_frame, b"geometry")
                    current_rect = banner_frame.geometry()
                    
                    original_rect = QRect(
                        current_rect.x() + 3,
                        current_rect.y() + 2,
                        current_rect.width() - 6,
                        current_rect.height() - 4
                    )
                    
                    animation.setDuration(200)
                    animation.setStartValue(current_rect)
                    animation.setEndValue(original_rect)
                    animation.setEasingCurve(QEasingCurve.InCubic)
                    animation.start()
                    
                    # 保存动画引用避免被垃圾回收
                    banner_frame.leave_animation = animation
                    
                except Exception as e:
                    print(f"[DEBUG] 离开动画错误: {e}")
            
            # 安装事件过滤器
            banner_frame.enterEvent = on_enter
            banner_frame.leaveEvent = on_leave
            
            # 添加到主布局
            layout.addWidget(banner_frame)
            
            print("[INFO] 宣传横幅已创建（使用图片，带悬停动画）")
            
        except Exception as e:
            print(f"[WARNING] 创建宣传横幅失败: {e}")
    
    # 横幅颜色动画相关方法已移除（改用图片横幅）

    def apply_modern_styles(self):
        """应用现代化简约样式 - 精致美化版"""
        self.setStyleSheet("""
            QMainWindow {
                background: qlineargradient(
                    x1:0, y1:0, x2:0, y2:1, 
                    stop:0 #f8fafb, 
                    stop:0.5 #f1f4f6,
                    stop:1 #e8ecef
                );
                border: 1px solid rgba(255, 255, 255, 0.3);
            }

            QLabel {
                color: #2c3e50;
                background: transparent;
            }

            QLabel[objectName="title"] {
                color: qlineargradient(
                    x1:0, y1:0, x2:1, y2:0,
                    stop:0 #2c3e50,
                    stop:1 #34495e
                );
                font-weight: bold;
            }

            QLabel[objectName="subtitle"] {
                color: #7f8c8d;
                background: transparent;
            }

            QLabel[objectName="status"] {
                padding: 5px 10px;
                border-radius: 12px;
                background: rgba(149, 165, 166, 0.1);
                font-size: 9px;
            }

            QLineEdit {
                padding: 12px 16px;
                border: 2px solid transparent;
                border-radius: 12px;
                font-size: 13px;
                background: qlineargradient(
                    x1:0, y1:0, x2:0, y2:1,
                    stop:0 #ffffff,
                    stop:1 #f8fafb
                );
                selection-background-color: #007bff;
                selection-color: white;
                color: #2c3e50;
            }

            QLineEdit:focus {
                border: 2px solid #007bff;
                background: white;
                outline: none;
            }

            QLineEdit:hover {
                border: 2px solid #6c757d;
                background: white;
            }

            QPushButton {
                background: qlineargradient(
                    x1:0, y1:0, x2:0, y2:1, 
                    stop:0 #4285f4, 
                    stop:0.5 #1976d2,
                    stop:1 #1565c0
                );
                border: none;
                color: white;
                padding: 12px 24px;
                border-radius: 12px;
                font-size: 13px;
                font-weight: 600;
                min-width: 180px;
                letter-spacing: 0.5px;
            }

            QPushButton:hover {
                background: qlineargradient(
                    x1:0, y1:0, x2:0, y2:1, 
                    stop:0 #5294f5, 
                    stop:0.5 #2986d3,
                    stop:1 #1e74c1
                );
            }

            QPushButton:pressed {
                background: qlineargradient(
                    x1:0, y1:0, x2:0, y2:1, 
                    stop:0 #3274d4, 
                    stop:0.5 #1666c2,
                    stop:1 #1455b0
                );
            }

            QPushButton:disabled {
                background: qlineargradient(
                    x1:0, y1:0, x2:0, y2:1,
                    stop:0 #f8f9fa,
                    stop:1 #e9ecef
                );
                color: #6c757d;
                border: 1px solid #dee2e6;
            }

            /* 连接成功状态的按钮 */
            QPushButton[objectName="connected"] {
                background: qlineargradient(
                    x1:0, y1:0, x2:0, y2:1, 
                    stop:0 #28a745, 
                    stop:0.5 #20963b,
                    stop:1 #1e7e34
                );
            }

            QPushButton[objectName="connected"]:hover {
                background: qlineargradient(
                    x1:0, y1:0, x2:0, y2:1, 
                    stop:0 #34ce57, 
                    stop:0.5 #28a745,
                    stop:1 #20963b
                );
            }
        """)

        # 设置全局字体，确保各Windows版本显示一致
        font = QFont('Microsoft YaHei', 10)  # Windows系统自带字体
        QApplication.setFont(font)

        # 设置调色板确保颜色一致性
        palette = QPalette()
        palette.setColor(QPalette.Window, QColor(248, 250, 251))
        palette.setColor(QPalette.WindowText, QColor(44, 62, 80))
        palette.setColor(QPalette.Base, QColor(255, 255, 255))
        palette.setColor(QPalette.AlternateBase, QColor(241, 244, 246))
        palette.setColor(QPalette.ToolTipBase, QColor(255, 255, 255))
        palette.setColor(QPalette.ToolTipText, QColor(44, 62, 80))
        palette.setColor(QPalette.Text, QColor(44, 62, 80))
        palette.setColor(QPalette.Button, QColor(66, 133, 244))
        palette.setColor(QPalette.ButtonText, QColor(255, 255, 255))
        palette.setColor(QPalette.BrightText, QColor(255, 255, 255))
        palette.setColor(QPalette.Highlight, QColor(66, 133, 244))
        palette.setColor(QPalette.HighlightedText, QColor(255, 255, 255))
        QApplication.setPalette(palette)

    def add_visual_effects(self):
        """添加视觉效果"""
        try:
            # 为主窗口添加阴影效果
            shadow = QGraphicsDropShadowEffect()
            shadow.setBlurRadius(20)
            shadow.setXOffset(0)
            shadow.setYOffset(5)
            shadow.setColor(QColor(0, 0, 0, 40))

            # 为输入框添加阴影
            input_shadow = QGraphicsDropShadowEffect()
            input_shadow.setBlurRadius(8)
            input_shadow.setXOffset(0)
            input_shadow.setYOffset(2)
            input_shadow.setColor(QColor(0, 0, 0, 20))
            self.token_input.setGraphicsEffect(input_shadow)

            # 为按钮添加阴影
            button_shadow = QGraphicsDropShadowEffect()
            button_shadow.setBlurRadius(12)
            button_shadow.setXOffset(0)
            button_shadow.setYOffset(4)
            button_shadow.setColor(QColor(66, 133, 244, 80))
            self.login_btn.setGraphicsEffect(button_shadow)

            # 设置对象名称以应用特定样式
            self.token_input.setObjectName("tokenInput")
            self.login_btn.setObjectName("loginButton")

            print("[INFO] 视觉效果已添加")

        except Exception as e:
            print(f"[WARNING] 添加视觉效果失败: {e}")

    def animate_success(self):
        """连接成功的动画效果"""
        try:
            # 按钮轻微放大动画
            self.button_animation = QPropertyAnimation(self.login_btn, b"geometry")
            original_rect = self.login_btn.geometry()

            # 计算放大后的位置（居中放大）
            expanded_rect = QRect(
                original_rect.x() - 5,
                original_rect.y() - 2,
                original_rect.width() + 10,
                original_rect.height() + 4
            )

            self.button_animation.setDuration(200)
            self.button_animation.setStartValue(original_rect)
            self.button_animation.setEndValue(expanded_rect)
            self.button_animation.setEasingCurve(QEasingCurve.OutBack)

            # 动画完成后恢复原始大小
            def restore_size():
                restore_animation = QPropertyAnimation(self.login_btn, b"geometry")
                restore_animation.setDuration(150)
                restore_animation.setStartValue(expanded_rect)
                restore_animation.setEndValue(original_rect)
                restore_animation.setEasingCurve(QEasingCurve.InBack)
                restore_animation.start()

            self.button_animation.finished.connect(restore_size)
            self.button_animation.start()

            print("[INFO] 成功动画已启动")

        except Exception as e:
            print(f"[WARNING] 动画效果失败: {e}")

    def on_platform_connected(self, platform_name: str, all_platforms: list):
        """处理平台连接成功事件"""
        try:
            import time
            self.connected_platforms = all_platforms.copy()
            self.last_platform_connect_time = time.time()

            # 短暂显示平台连接成功提示
            self.status_label.setText(f"🟢 {platform_name}平台连接成功！")
            self.status_label.setStyleSheet(
                "color: #28a745; background: rgba(40, 167, 69, 0.15); border-radius: 12px; padding: 5px 10px; font-weight: bold;")

            # 停止之前的定时器
            if self.status_timer:
                self.status_timer.stop()
                self.status_timer = None

            self.add_log(f"GUI收到平台连接通知: {platform_name}, 当前已连接: {', '.join(all_platforms)}", "INFO")

            # 使用线程定时器，更可靠（资源消耗极小）
            import threading

            def delayed_update():
                import time
                time.sleep(3)  # 等待3秒
                # 使用QTimer.singleShot确保在主线程中执行GUI更新
                QTimer.singleShot(0, self.delayed_platform_summary)

            # 启动轻量级守护线程（3秒后自动销毁）
            timer_thread = threading.Thread(target=delayed_update, daemon=True)
            timer_thread.start()

            self.add_log("3秒线程定时器已启动，将自动切换到汇总显示", "INFO")

        except Exception as e:
            self.add_log(f"处理平台连接事件失败: {e}", "ERROR")

    def on_platform_kicked(self, platform_name: str, store_name: str, reason: str):
        """处理平台被踢下线 - 显示弹窗警告"""
        try:
            self.add_log(f"⚠️ {platform_name}平台被踢下线: {store_name}, 原因: {reason}", "WARNING")
            
            # 显示弹窗提示
            message_text = (
                f"【{store_name}】连接已断开\n\n"
                f"原因：{reason}\n\n"
                f"请确保：\n"
                f"1. 关闭网页版{platform_name}客户端\n"
                f"2. 关闭其他{platform_name}客户端\n"
                f"3. 确认只有本程序连接\n\n"
                f"处理完成后，请重新登录平台。"
            )
            QMessageBox.warning(
                self,
                f"{platform_name}连接已断开",
                message_text,
                QMessageBox.Ok
            )
            
            # 更新状态显示
            self.status_label.setText(f"⚠️ {platform_name}已断开")
            self.status_label.setStyleSheet(
                "color: #ff6b6b; background: rgba(255, 107, 107, 0.1); border-radius: 12px; padding: 5px 10px;")
            
        except Exception as e:
            self.add_log(f"显示平台断开提示失败: {e}", "ERROR")

    def on_token_error(self, error_content: str):
        """处理token错误 - 显示红色错误信息并停止所有操作"""
        try:
            self.add_log(f"Token验证失败: {error_content}", "ERROR")

            # 在状态标签显示红色错误信息
            self.status_label.setText(f"🔴 {error_content}")
            self.status_label.setStyleSheet(
                "color: #dc3545; background: rgba(220, 53, 69, 0.1); border-radius: 12px; padding: 5px 10px; font-weight: bold;")

            # 重置按钮状态
            self.login_btn.setEnabled(True)
            self.login_btn.setText("重新连接")
            self.login_btn.setObjectName("loginButton")  # 恢复原始样式

            # 清空已连接平台列表
            self.connected_platforms.clear()

            self.add_log("由于token无效，已停止所有连接操作", "ERROR")

        except Exception as e:
            self.add_log(f"处理token错误失败: {e}", "ERROR")

    def on_disconnect(self, disconnect_msg: str):
        """处理被踢下线 - 发射信号到主线程（可在任何线程中调用）"""
        try:
            self.add_log(f"📡 收到断开通知，准备发射信号: {disconnect_msg}", "INFO")
            # 发射信号（Qt 自动调度到主线程）
            self.disconnect_signals.disconnected.emit(disconnect_msg)
            self.add_log(f"✅ 断开信号已发射", "DEBUG")
        except Exception as e:
            self.add_log(f"❌ 发射断开信号失败: {e}", "ERROR")
            import traceback
            self.add_log(f"详细错误: {traceback.format_exc()}", "ERROR")

    def _show_disconnect_dialog(self, disconnect_msg: str):
        """显示断开连接提示框（信号槽函数，始终在主线程中执行）"""
        try:
            self.add_log(f"🎯 主线程收到断开信号: {disconnect_msg}", "INFO")

            # 在状态标签显示警告信息
            self.status_label.setText(f"⚠️ 账号在其他设备登录")
            self.status_label.setStyleSheet(
                "color: #ff9800; background: rgba(255, 152, 0, 0.1); border-radius: 12px; padding: 5px 10px; font-weight: bold;")

            # 重置按钮状态
            self.login_btn.setEnabled(True)
            self.login_btn.setText("重新连接")
            self.login_btn.setObjectName("loginButton")  # 恢复原始样式
            self.login_btn.setStyleSheet(self.login_btn.styleSheet())  # 刷新样式

            # 清空已连接平台列表
            self.connected_platforms.clear()

            # 显示友好的提示对话框（主线程中执行，不会卡顿）
            QMessageBox.warning(
                self,
                "连接已断开",
                f"{disconnect_msg}\n\n"
                "如果是您本人在其他设备登录，可以忽略此提示。\n"
                "如需继续使用，请点击\"重新连接\"按钮。",
                QMessageBox.Ok
            )

            self.add_log("连接已断开，您可以重新连接", "INFO")

        except Exception as e:
            self.add_log(f"❌ 显示断开提示框失败: {e}", "ERROR")
            import traceback
            self.add_log(f"详细错误: {traceback.format_exc()}", "ERROR")

    def delayed_platform_summary(self):
        """定时器触发的汇总显示更新"""
        try:
            self.add_log("🎯 定时器触发！开始执行汇总显示更新", "INFO")
            self.update_platform_summary()
            self.add_log("🎯 定时器执行完成", "INFO")
        except Exception as e:
            self.add_log(f"定时器执行失败: {e}", "ERROR")

    def check_and_update_summary(self):
        """检查是否应该更新汇总显示"""
        try:
            import time
            elapsed = time.time() - self.last_platform_connect_time
            self.add_log(f"检查汇总更新: 距离最后连接 {elapsed:.1f} 秒", "INFO")

            # 检查是否在最近1秒内还有新的平台连接
            if elapsed >= 2.8:  # 距离最后连接超过2.8秒
                self.add_log("满足条件，开始更新汇总显示", "INFO")
                self.update_platform_summary()
            else:
                # 如果还有新连接，再延迟一会儿
                self.add_log(f"还需等待 {2.8 - elapsed:.1f} 秒，延迟更新", "INFO")
                QTimer.singleShot(1000, self.check_and_update_summary)
        except Exception as e:
            self.add_log(f"检查汇总更新失败: {e}", "ERROR")

    def update_platform_summary(self):
        """更新平台连接汇总显示"""
        try:
            self.add_log(f"开始更新汇总显示，当前连接平台: {self.connected_platforms}", "INFO")

            if self.connected_platforms:
                platforms_text = "、".join(self.connected_platforms)
                summary_text = f"🟢 已连接: {platforms_text}"
                self.status_label.setText(summary_text)
                self.status_label.setStyleSheet(
                    "color: #28a745; background: rgba(40, 167, 69, 0.1); border-radius: 12px; padding: 5px 10px;")
                self.add_log(f"汇总显示已更新: {summary_text}", "INFO")
            else:
                self.status_label.setText("🟢 连接成功！等待平台指令...")
                self.status_label.setStyleSheet(
                    "color: #28a745; background: rgba(40, 167, 69, 0.1); border-radius: 12px; padding: 5px 10px;")
                self.add_log("已更新为等待平台指令状态", "INFO")
        except Exception as e:
            self.add_log(f"更新平台汇总显示失败: {e}", "ERROR")

    def init_system_tray(self):
        """初始化系统托盘"""
        # 检查系统是否支持托盘
        if not QSystemTrayIcon.isSystemTrayAvailable():
            QMessageBox.critical(None, "系统托盘",
                                 "系统托盘不可用")
            return

        # 创建托盘图标
        self.tray_icon = QSystemTrayIcon(self)

        # 使用自定义的美观图标
        try:
            # 导入路径处理函数
            from windows_taskbar_fix import get_resource_path
            tray_icon_path = get_resource_path("static/ai_assistant_icon_16.png")
            if os.path.exists(tray_icon_path):
                from PyQt5.QtGui import QIcon
                self.tray_icon.setIcon(QIcon(tray_icon_path))
                print(f"[INFO] 已加载托盘图标: {tray_icon_path}")
            else:
                print(f"[WARNING] 托盘图标文件不存在: {tray_icon_path}")
                # 备用方案：使用系统图标
                self.tray_icon.setIcon(self.style().standardIcon(self.style().SP_ComputerIcon))
        except Exception as e:
            print(f"[WARNING] 加载托盘图标失败: {e}, 使用默认图标")
            # 备用方案：使用系统图标
            self.tray_icon.setIcon(self.style().standardIcon(self.style().SP_ComputerIcon))

        # 创建托盘菜单
        self.tray_menu = QMenu()

        # 连接菜单显示信号，实时更新状态
        self.tray_menu.aboutToShow.connect(self.update_tray_menu)

        # 初始化菜单内容
        self.update_tray_menu()

        # 设置托盘菜单
        self.tray_icon.setContextMenu(self.tray_menu)

        # 设置托盘提示
        self.tray_icon.setToolTip("AI客服智能助手")

        # 双击托盘图标显示窗口
        self.tray_icon.activated.connect(self.tray_icon_activated)

        # 显示托盘图标
        self.tray_icon.show()

        print("[INFO] 系统托盘已初始化")

    def update_tray_menu(self):
        """实时更新托盘菜单，显示连接状态"""
        try:
            # 清空现有菜单
            self.tray_menu.clear()
            
            # 获取WebSocket管理器
            ws_manager = get_websocket_manager()
            
            # 1. 显示后端连接状态
            if ws_manager and ws_manager.backend_client and ws_manager.backend_client.is_connected:
                backend_status = QAction("✅ 后端已连接", self)
                backend_status.setEnabled(False)  # 不可点击
                self.tray_menu.addAction(backend_status)
                
                # 2. 显示已连接的平台信息
                platform_listeners = ws_manager.platform_listeners
                if platform_listeners:
                    # 按平台分组店铺
                    platform_stores = {}
                    for key, info in platform_listeners.items():
                        platform = info.get('platform', '')
                        store_name = info.get('store_name', '')
                        store_id = info.get('store_id', '')
                        
                        if platform not in platform_stores:
                            platform_stores[platform] = []
                        
                        # 优先显示店铺名称，如果没有则显示 store_id 前8位
                        if store_name:
                            display_name = store_name
                        else:
                            display_name = store_id[:8] + "..." if len(store_id) > 8 else store_id
                        
                        platform_stores[platform].append(display_name)
                    
                    # 显示每个平台的店铺
                    for platform, stores in platform_stores.items():
                        stores_text = ", ".join(stores)
                        platform_info = QAction(f"📊 {platform}: {stores_text}", self)
                        platform_info.setEnabled(False)  # 不可点击
                        self.tray_menu.addAction(platform_info)
                else:
                    # 后端已连接但没有平台连接
                    no_platform = QAction("⚠️ 暂无平台连接", self)
                    no_platform.setEnabled(False)
                    self.tray_menu.addAction(no_platform)
            else:
                # 后端未连接
                backend_disconnected = QAction("❌ 后端未连接", self)
                backend_disconnected.setEnabled(False)
                self.tray_menu.addAction(backend_disconnected)
            
            # 添加分隔线
            self.tray_menu.addSeparator()
            
            # 3. 显示主窗口
            show_action = QAction("显示主窗口", self)
            show_action.triggered.connect(self.show_window)
            self.tray_menu.addAction(show_action)
            
            # 添加分隔线
            self.tray_menu.addSeparator()
            
            # 4. 退出程序
            quit_action = QAction("退出程序", self)
            quit_action.triggered.connect(self.quit_application)
            self.tray_menu.addAction(quit_action)
            
        except Exception as e:
            print(f"[ERROR] 更新托盘菜单失败: {e}")
            # 如果更新失败，至少保证基本功能可用
            self.tray_menu.clear()
            show_action = QAction("显示主窗口", self)
            show_action.triggered.connect(self.show_window)
            self.tray_menu.addAction(show_action)
            
            quit_action = QAction("退出程序", self)
            quit_action.triggered.connect(self.quit_application)
            self.tray_menu.addAction(quit_action)

    def tray_icon_activated(self, reason):
        """托盘图标被激活时的处理"""
        if reason == QSystemTrayIcon.DoubleClick:
            self.show_window()

    def show_window(self):
        """显示主窗口"""
        self.show()
        self.raise_()
        self.activateWindow()
        print("[INFO] 主窗口已显示")

    def quit_application(self):
        """真正退出应用程序"""
        print("[INFO] 正在退出应用程序...")

        # 执行原来的关闭逻辑
        try:
            # 使用 WebSocket 管理器断开所有连接
            from WebSocket.backend_singleton import get_websocket_manager
            ws_manager = get_websocket_manager()
            ws_manager.disconnect_all()

            # 停止所有工作线程（向后兼容）
            workers = []
            if hasattr(self, 'jd_worker') and self.jd_worker:
                workers.append(self.jd_worker)
            if hasattr(self, 'douyin_worker') and self.douyin_worker:
                workers.append(self.douyin_worker)
            if hasattr(self, 'qian_niu_worker') and self.qian_niu_worker:
                workers.append(self.qian_niu_worker)
            if hasattr(self, 'pdd_worker') and self.pdd_worker:
                workers.append(self.pdd_worker)

            # 停止所有线程
            for worker in workers:
                if worker.isRunning():
                    worker.stop()
                    worker.quit()
                    worker.wait(1000)

            # 强制关闭事件循环
            for worker in workers:
                if hasattr(worker, 'loop') and worker.loop and not worker.loop.is_closed():
                    worker.loop.close()

        except Exception as e:
            print(f"关闭时发生错误: {str(e)}")
        finally:
            # 隐藏托盘图标
            if hasattr(self, 'tray_icon'):
                self.tray_icon.hide()

            # 退出应用程序
            QApplication.quit()

    def add_log(self, message, log_type="INFO"):
        """添加日志信息 - 只输出到终端"""
        from datetime import datetime
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

        # 根据日志类型设置颜色（ANSI颜色码）
        colors = {
            "ERROR": "\033[91m",  # 红色
            "SUCCESS": "\033[92m",  # 绿色
            "WARNING": "\033[93m",  # 黄色
            "INFO": "\033[94m",  # 蓝色
            "DEBUG": "\033[95m"  # 紫色
        }
        reset = "\033[0m"  # 重置颜色

        color = colors.get(log_type, colors["INFO"])
        log_entry = f"{color}[{timestamp}] [{log_type}] {message}{reset}"
        print(log_entry)

    def login(self):
        """处理连接逻辑"""
        # 防止重复快速点击
        import time
        current_time = time.time()
        if current_time - self.last_login_time < self.login_cooldown:
            self.add_log(f"请等待 {self.login_cooldown} 秒后再试", "WARNING")
            return

        self.last_login_time = current_time

        token = self.token_input.text().strip()
        if not token:
            self.add_log("请输入有效的连接令牌", "ERROR")
            return

        # 禁用连接按钮，防止重复点击
        self.login_btn.setEnabled(False)
        self.login_btn.setText("连接中...")
        self.status_label.setText("正在连接服务...")
        self.status_label.setStyleSheet("color: #ffc107;")

        success = False
        try:
            # 使用 WebSocket 管理器处理连接
            ws_manager = get_websocket_manager()

            # 设置回调函数
            ws_manager.set_callbacks(
                log=self.add_log,
                success=lambda: self.add_log("WebSocket连接管理器连接成功", "SUCCESS"),
                error=lambda error: self.add_log(f"WebSocket连接管理器错误: {error}", "ERROR"),
                platform_connected=self.on_platform_connected,  # 新增：平台连接回调
                platform_disconnected=self.on_platform_kicked,  # 新增：平台被踢回调
                token_error=self.on_token_error,  # 新增：token错误回调
                disconnect=self.on_disconnect  # 新增：被踢下线回调
            )

            # 连接后端
            success = ws_manager.connect_backend(token)

            if success:
                self.add_log("已启动WebSocket连接管理器", "SUCCESS")
                self.status_label.setText("🟢 连接成功！等待平台指令...")
                self.status_label.setStyleSheet(
                    "color: #28a745; background: rgba(40, 167, 69, 0.1); border-radius: 12px; padding: 5px 10px;")
                self.login_btn.setText("✓ 已连接")
                self.login_btn.setObjectName("connected")
                self.login_btn.setStyleSheet(self.login_btn.styleSheet())  # 刷新样式

                # 添加成功动画效果
                self.animate_success()
            else:
                self.add_log("WebSocket连接管理器启动失败", "ERROR")
                self.status_label.setText("🔴 连接失败，请检查令牌")
                self.status_label.setStyleSheet(
                    "color: #dc3545; background: rgba(220, 53, 69, 0.1); border-radius: 12px; padding: 5px 10px;")

        except Exception as e:
            self.add_log(f"连接失败: {e}", "ERROR")
            self.status_label.setText(f"🔴 连接失败: {str(e)}")
            self.status_label.setStyleSheet(
                "color: #dc3545; background: rgba(220, 53, 69, 0.1); border-radius: 12px; padding: 5px 10px;")
        finally:
            self.login_btn.setEnabled(True)
            if not success:
                self.login_btn.setText("重新连接")
                self.login_btn.setObjectName("loginButton")  # 恢复原始样式

    def verify_token(self, token):
        """简化的令牌校验：非空即通过（实际校验由后端承担）"""
        return bool(token)

    def closeEvent(self, event):
        """窗口关闭事件处理 - 最小化到托盘"""
        if hasattr(self, 'tray_icon') and self.tray_icon.isVisible():
            # 首次最小化时显示提示消息
            if not hasattr(self, '_tray_message_shown'):
                self.tray_icon.showMessage(
                    "AI客服智能助手",
                    "程序已最小化到系统托盘。双击托盘图标可重新显示窗口。",
                    QSystemTrayIcon.Information,
                    3000
                )
                self._tray_message_shown = True

            # 隐藏窗口而不是关闭
            self.hide()
            event.ignore()
            print("[INFO] 窗口已最小化到系统托盘")
        else:
            # 如果托盘不可用，则正常退出
            self.quit_application()
            event.accept()

    def setup_version_checker(self):
        """设置版本检查器的GUI回调"""
        try:
            from WebSocket.backend_singleton import get_websocket_manager
            ws_manager = get_websocket_manager()
            if ws_manager:
                # 设置回调为信号发射函数（线程安全）
                ws_manager.gui_update_callback = self.emit_update_signal
                self.add_log("✅ 版本检查器GUI回调已设置", "SUCCESS")
            else:
                self.add_log("⚠️ WebSocket管理器未初始化", "WARNING")
        except Exception as e:
            self.add_log(f"❌ 设置版本检查器失败: {e}", "ERROR")

    def emit_update_signal(self, latest_version, download_url):
        """发射更新信号（可以在任何线程中调用）"""
        try:
            self.add_log(f"📡 收到更新通知，准备发射信号: v{latest_version}", "INFO")
            # 发射信号（Qt 自动调度到主线程）
            self.update_signals.update_available.emit(latest_version, download_url)
            self.add_log(f"✅ 更新信号已发射", "DEBUG")
        except Exception as e:
            self.add_log(f"❌ 发射更新信号失败: {e}", "ERROR")
            import traceback
            self.add_log(f"详细错误: {traceback.format_exc()}", "ERROR")

    def _show_update_dialog(self, latest_version, download_url):
        """显示更新对话框（信号槽函数，始终在主线程中执行）"""
        try:
            self.add_log(f"🎯 主线程收到更新信号: v{latest_version}", "INFO")
            self.show_update_notification(latest_version, download_url)
        except Exception as e:
            self.add_log(f"❌ 显示更新对话框失败: {e}", "ERROR")
            import traceback
            self.add_log(f"详细错误: {traceback.format_exc()}", "ERROR")

    def show_update_notification(self, latest_version, download_url):
        """显示版本更新通知"""
        try:
            self.add_log(f"🔔 准备显示更新通知: v{latest_version}", "INFO")
            self.add_log(f"   下载地址: {download_url if download_url else '(空)'}", "INFO")

            # 读取更新内容
            update_content = self._get_update_content(latest_version)

            # 检查下载地址
            if not download_url or download_url.strip() == "":
                # 下载地址为空，只显示通知，不提供下载
                message = f"发现新版本 {latest_version}！\n\n"
                if update_content:
                    message += f"更新内容：\n{update_content}\n\n"
                message += "下载地址暂未配置，请稍后再试或联系管理员。"

                QMessageBox.information(
                    self,
                    "版本更新",
                    message,
                    QMessageBox.Ok
                )
                self.add_log(f"⚠️ 新版本 {latest_version} 的下载地址为空，已通知用户", "WARNING")
                return  # 安全返回，不崩溃

            # 下载地址有效，显示更新对话框
            message = f"发现新版本 {latest_version}，是否立即更新？\n\n"

            if update_content:
                message += f"更新内容：\n{update_content}\n\n"

            message += "点击确定将打开下载页面。"

            reply = QMessageBox.question(
                self,
                "版本更新",
                message,
                QMessageBox.Yes | QMessageBox.No,
                QMessageBox.Yes
            )

            if reply == QMessageBox.Yes:
                self.add_log("用户选择立即更新", "INFO")
                self.trigger_update(download_url, latest_version)
            else:
                self.add_log("用户选择稍后更新", "INFO")
                # 用户点击"否"，不做任何操作，程序继续运行

        except Exception as e:
            self.add_log(f"❌ 显示更新通知失败: {e}", "ERROR")
            import traceback
            self.add_log(f"详细错误: {traceback.format_exc()}", "ERROR")

    def _get_update_content(self, version):
        """获取版本更新内容"""
        try:
            import json
            version_file = "version_history.json"

            if not os.path.exists(version_file):
                return ""

            with open(version_file, 'r', encoding='utf-8') as f:
                history = json.load(f)

            # 查找对应版本
            for record in history:
                if record.get('version') == version:
                    content = record.get('content', '')
                    # 去掉 [patch]/[minor]/[major] 标记
                    import re
                    content = re.sub(r'\[(patch|minor|major)\]\s*', '', content, flags=re.IGNORECASE)
                    # 限制长度
                    if len(content) > 150:
                        content = content[:150] + "..."
                    return content

            return ""

        except Exception as e:
            self.add_log(f"⚠️ 读取更新内容失败: {e}", "DEBUG")
            return ""

    def trigger_update(self, download_url, latest_version):
        """触发更新下载（不阻塞主程序）"""
        import webbrowser
        import threading

        # 检查下载地址是否有效
        if not download_url or download_url.strip() == "":
            self.add_log("⚠️ 下载地址为空，无法打开更新页面", "WARNING")
            QMessageBox.warning(
                self,
                "下载地址缺失",
                f"版本 {latest_version} 的下载地址暂未配置。\n\n请联系管理员或稍后再试。",
                QMessageBox.Ok
            )
            return

        # 明确提示用户即将下载
        reply = QMessageBox.information(
            self,
            "准备下载更新",
            f"即将打开浏览器下载 v{latest_version} 安装包。\n\n"
            f"下载完成后请：\n"
            f"1. 关闭本程序\n"
            f"2. 运行下载的安装包\n"
            f"3. 按照提示完成更新\n\n"
            f"点击确定继续...",
            QMessageBox.Ok | QMessageBox.Cancel,
            QMessageBox.Ok
        )

        if reply == QMessageBox.Cancel:
            self.add_log("用户取消下载", "INFO")
            return

        self.add_log(f"📂 准备打开下载页面: {download_url}", "INFO")

        # 在独立线程中打开浏览器，确保不阻塞GUI主线程
        def open_browser_thread():
            try:
                webbrowser.open(download_url)
                self.add_log("✅ 浏览器已打开，下载即将开始", "SUCCESS")
            except Exception as e:
                self.add_log(f"❌ 打开浏览器失败: {e}", "ERROR")

        thread = threading.Thread(target=open_browser_thread, daemon=True)
        thread.start()

        self.add_log("✅ 已启动下载，程序继续运行", "INFO")


def main():
    """主函数，用于测试界面"""
    app = QApplication(sys.argv)

    # 设置应用程序属性
    app.setApplicationName(config.WINDOW_TITLE)
    app.setApplicationVersion(config.VERSION)

    # 设置应用程序唯一ID（重要：避免和Python默认图标混淆）
    try:
        import ctypes
        # 设置应用程序用户模型ID，让Windows识别为独立应用
        ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("ShuidropAI.CustomerService.1.0")
        print("[INFO] 已设置应用程序唯一ID")
    except Exception as e:
        print(f"[WARNING] 设置应用程序ID失败: {e}")

    # 创建主窗口
    window = LoginWindow()

    # 统一设置所有图标（使用任务栏修复模块）
    try:
        app_icon = setup_windows_taskbar_icon(app, window)
        print("[INFO] 所有图标设置完成")
    except Exception as e:
        print(f"[WARNING] 图标设置失败: {e}")
        # 备用方案：使用简单的图标设置
        try:
            # 导入路径处理函数
            from windows_taskbar_fix import get_resource_path
            icon_path = get_resource_path("static/ai_assistant_icon_32.png")
            if os.path.exists(icon_path):
                from PyQt5.QtGui import QIcon
                backup_icon = QIcon(icon_path)
                app.setWindowIcon(backup_icon)
                window.setWindowIcon(backup_icon)
                print(f"[INFO] 已使用备用图标: {icon_path}")
        except Exception as e2:
            print(f"[ERROR] 备用图标也设置失败: {e2}")

    window.show()  # 程序启动断点

    # 运行应用程序
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()  # sd_acF0TisgfFOtsBm4ytqb17MQbcxuX9Vp  测试令牌(token)
    # username = "KLD测试"
    #     password = "kld168168"
    # taobao nickname = "tb420723827:redboat"

