#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
模块名称：paperless_simulator.py
模块描述：无纸化会议设备模拟器

作者：czj
创建日期：2026-07-29
最后修改：2026-07-29
"""

import json
import logging
import random
import time
from typing import Optional

from app.simulators.base_simulator import BaseSimulator
from app.services.mqtt_manager import MqttManager

logger = logging.getLogger(__name__)


class PaperlessSimulator(BaseSimulator):
    """
    无纸化会议设备模拟器

    模拟无纸化会议终端，支持：
    - 设备注册与状态上报
    - 参会人员签到/签退
    - 会议文件同步状态
    - 投屏开始/结束/异常
    - 会议状态变化

    Attributes:
        _meeting_status (str): 会议状态 (idle/active/ended)
        _signed_in (bool): 是否已签到
        _file_sync_progress (int): 文件同步进度 (0-100)
        _screen_sharing (bool): 是否正在投屏
    """

    # 会议议题列表
    _AGENDA_ITEMS = [
        "会议开场致辞",
        "上季度工作总结",
        "项目进度汇报",
        "技术方案评审",
        "预算审批",
        "下季度计划制定",
        "自由讨论",
        "会议总结"
    ]

    def __init__(self, device_id: str, env_config_id: str,
                 mqtt_manager: MqttManager, report_interval: int = 30,
                 topics: Optional[dict] = None):
        super().__init__(device_id, env_config_id, "paperless", mqtt_manager,
                         report_interval, topics)
        self._meeting_status = "idle"
        self._signed_in = False
        self._file_sync_progress = 0
        self._screen_sharing = False
        self._current_agenda = ""

    def build_register_payload(self) -> dict:
        """构建设备注册消息"""
        return {
            "device_id": self.device_id,
            "device_type": "paperless_terminal",
            "name": f"无纸化终端-{self.device_id}",
            "model": "MT-21P",
            "version": "V3.2.1",
            "screen_size": "21.5英寸",
            "resolution": "1920x1080",
            "capabilities": ["sign_in", "file_sync", "screen_share", "meeting_control"]
        }

    def build_status_payload(self) -> dict:
        """构建设备状态上报消息"""
        return {
            "device_id": self.device_id,
            "status": "online",
            "meeting_status": self._meeting_status,
            "signed_in": self._signed_in,
            "screen_sharing": self._screen_sharing,
            "cpu_usage": random.randint(20, 80),
            "memory_usage": random.randint(30, 70),
            "disk_usage": random.randint(20, 60),
            "timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
        }

    def _on_command(self, topic: str, payload: dict) -> None:
        """
        处理平台下发的指令

        支持的指令：
        - start_meeting: 开始会议
        - end_meeting: 结束会议
        - start_screen_share: 开始投屏
        - stop_screen_share: 停止投屏
        - sync_file: 同步文件
        """
        try:
            command = payload.get("command", "")
            logger.info(f"无纸化设备收到指令: device_id={self.device_id}, command={command}")

            # 记录接收到的平台下发指令（direction=subscribe）
            command_topic = f"{self.get_topic_prefix()}/{self.device_id}/command"
            self._notify_report(
                command_topic,
                payload,
                direction="subscribe",
                status="success"
            )

            response_topic = f"{self.get_topic_prefix()}/{self.device_id}/command_response"

            if command == "start_meeting":
                self._meeting_status = "active"
                self._current_agenda = self._AGENDA_ITEMS[0]
                self._file_sync_progress = 0
                self._notify_report(response_topic, {
                    "device_id": self.device_id,
                    "command": "start_meeting",
                    "result": "success",
                    "meeting_name": f"会议-{time.strftime('%Y%m%d')}"
                })

            elif command == "end_meeting":
                self._meeting_status = "ended"
                self._signed_in = False
                self._screen_sharing = False
                self._notify_report(response_topic, {
                    "device_id": self.device_id,
                    "command": "end_meeting",
                    "result": "success",
                    "duration_minutes": random.randint(30, 120)
                })

            elif command == "start_screen_share":
                self._screen_sharing = True
                self._notify_report(response_topic, {
                    "device_id": self.device_id,
                    "command": "start_screen_share",
                    "result": "success",
                    "share_content": self._current_agenda or "桌面"
                })

            elif command == "stop_screen_share":
                self._screen_sharing = False
                self._notify_report(response_topic, {
                    "device_id": self.device_id,
                    "command": "stop_screen_share",
                    "result": "success"
                })

            elif command == "sync_file":
                # 模拟文件同步
                self._file_sync_progress = 0
                self._simulate_file_sync()
                self._notify_report(response_topic, {
                    "device_id": self.device_id,
                    "command": "sync_file",
                    "result": "success",
                    "message": "文件同步已开始"
                })

            else:
                self._notify_report(response_topic, {
                    "device_id": self.device_id,
                    "command": command,
                    "result": "unknown",
                    "message": f"不支持的指令: {command}"
                })

        except Exception as e:
            logger.error(f"无纸化设备指令处理异常: {e}")

    def _simulate_file_sync(self) -> None:
        """模拟文件同步进度"""
        import threading as t

        def _sync():
            for i in range(1, 11):
                if not self._running:
                    break
                time.sleep(1)
                self._file_sync_progress = i * 10
                # 上报同步进度
                sync_topic = f"{self.get_topic_prefix()}/{self.device_id}/file_sync"
                self.mqtt.publish(self.env_config_id, sync_topic, {
                    "device_id": self.device_id,
                    "progress": self._file_sync_progress,
                    "file_name": f"meeting_materials_{time.strftime('%Y%m%d')}.pdf",
                    "file_size_mb": random.randint(5, 50),
                    "status": "syncing" if i < 10 else "completed"
                })

        t.Thread(target=_sync, daemon=True).start()

    def trigger_sign_in(self, user_name: Optional[str] = None) -> bool:
        """
        触发签到上报

        Args:
            user_name: 签到用户名称

        Returns:
            bool: 是否上报成功
        """
        self._signed_in = True
        payload = {
            "device_id": self.device_id,
            "action": "sign_in",
            "user_name": user_name or f"参会人员_{random.randint(1, 50)}",
            "department": random.choice(["研发部", "产品部", "测试部", "运维部", "市场部"]),
            "sign_time": time.strftime("%Y-%m-%d %H:%M:%S"),
            "meeting_name": f"会议-{time.strftime('%Y%m%d')}"
        }
        return self.report("signin", payload)

    def trigger_sign_out(self) -> bool:
        """触发签退上报"""
        self._signed_in = False
        payload = {
            "device_id": self.device_id,
            "action": "sign_out",
            "sign_time": time.strftime("%Y-%m-%d %H:%M:%S")
        }
        return self.report("signin", payload)

    def trigger_screen_status(self, status: str = "sharing") -> bool:
        """
        触发投屏状态上报

        Args:
            status: 投屏状态 (sharing/stopped/error)

        Returns:
            bool: 是否上报成功
        """
        payloads = {
            "sharing": {
                "device_id": self.device_id,
                "status": "sharing",
                "content": self._current_agenda or "桌面",
                "start_time": time.strftime("%Y-%m-%d %H:%M:%S")
            },
            "stopped": {
                "device_id": self.device_id,
                "status": "stopped",
                "reason": "normal",
                "duration_seconds": random.randint(60, 600)
            },
            "error": {
                "device_id": self.device_id,
                "status": "error",
                "error_code": "SCREEN_001",
                "error_message": "投屏连接中断"
            }
        }
        payload = payloads.get(status, payloads["sharing"])
        return self.report("screen", payload)