#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
用户使用统计模块
只统计有多少人在使用这个系统
"""

import asyncio
import hashlib
import platform
from datetime import datetime
from typing import Dict, Any

import aiohttp
from loguru import logger


class UsageStatistics:
    """用户使用统计收集器 - 只统计用户数量"""

    def __init__(self):
        # 默认启用统计
        self.enabled = True
        self.api_endpoint = "http://xianyu.zhinianblog.cn/?action=statistics"  # PHP统计接收端点
        self.timeout = 5
        self.retry_count = 1

        # 生成持久化的匿名用户ID
        self.anonymous_id = self._get_or_create_anonymous_id()

    def _get_or_create_anonymous_id(self) -> str:
        """获取或创建持久化的匿名用户ID"""
        # 保存到数据库中，确保Docker重建时ID不变
        try:
            from db_manager import db_manager

            # 尝试从数据库获取ID
            existing_id = db_manager.get_system_setting('anonymous_user_id')
            if existing_id and len(existing_id) == 16:
                return existing_id

        except Exception:
            pass

        # 生成新的匿名ID
        new_id = self._generate_anonymous_id()

        # 保存到数据库
        try:
            from db_manager import db_manager
            db_manager.set_system_setting('anonymous_user_id', new_id)
        except Exception:
            pass

        return new_id

    def _generate_anonymous_id(self) -> str:
        """生成匿名用户ID（基于机器特征）"""
        try:
            # 使用系统信息生成唯一但匿名的ID
            machine_info = f"{platform.machine()}-{platform.processor()}-{platform.system()}"
            unique_str = f"{machine_info}-{platform.python_version()}"

            # 生成哈希值作为匿名ID
            anonymous_id = hashlib.sha256(unique_str.encode()).hexdigest()[:16]
            return anonymous_id
        except Exception:
            # 如果获取系统信息失败，使用随机ID
            import time
            return hashlib.md5(str(time.time()).encode()).hexdigest()[:16]
    
    def _get_basic_info(self) -> Dict[str, Any]:
        """获取基本信息（只包含必要信息）"""
        try:
            # 从version.txt文件读取版本号
            version = self._get_version()
            return {
                "os": platform.system(),
                "version": version
            }
        except Exception:
            return {"os": "unknown", "version": "unknown"}

    def _get_version(self) -> str:
        """从static/version.txt文件获取版本号"""
        try:
            with open("static/version.txt", "r", encoding="utf-8") as f:
                version = f.read().strip()
                return version if version else "unknown"
        except Exception:
            return "unknown"
    
    def _prepare_statistics_data(self) -> Dict[str, Any]:
        """准备统计数据（只包含用户统计）"""
        return {
            "anonymous_id": self.anonymous_id,
            "timestamp": datetime.now().isoformat(),
            "project": "xianyu-auto-reply",
            "info": self._get_basic_info()
        }
    
    async def _send_statistics(self, data: Dict[str, Any]) -> bool:
        """发送统计数据到远程API"""
        if not self.enabled:
            return False

        for attempt in range(self.retry_count):
            try:
                timeout = aiohttp.ClientTimeout(total=self.timeout)
                async with aiohttp.ClientSession(timeout=timeout) as session:
                    headers = {
                        'Content-Type': 'application/json',
                        'User-Agent': 'XianyuAutoReply/2.2.0'
                    }

                    async with session.post(
                        self.api_endpoint,
                        json=data,
                        headers=headers
                    ) as response:
                        if response.status in [200, 201]:
                            logger.debug("统计数据上报成功")
                            return True
                        else:
                            logger.debug(f"统计数据上报失败，状态码: {response.status}")

            except asyncio.TimeoutError:
                logger.debug(f"统计数据上报超时，第{attempt + 1}次尝试")
            except Exception as e:
                logger.debug(f"统计数据上报异常: {e}")

            if attempt < self.retry_count - 1:
                await asyncio.sleep(1)

        return False
    
    async def report_usage(self) -> bool:
        """报告用户使用统计"""
        try:
            data = self._prepare_statistics_data()
            return await self._send_statistics(data)
        except Exception as e:
            logger.debug(f"报告使用统计失败: {e}")
            return False


# 全局统计实例
usage_stats = UsageStatistics()


async def report_user_count():
    """报告用户数量统计"""
    try:
        logger.info("正在上报用户统计...")
        success = await usage_stats.report_usage()
        if success:
            logger.info("✅ 用户统计上报成功")
        else:
            logger.debug("用户统计上报失败")
    except Exception as e:
        logger.debug(f"用户统计异常: {e}")


def get_anonymous_id() -> str:
    """获取匿名用户ID"""
    return usage_stats.anonymous_id


# 测试函数
async def test_statistics():
    """测试统计功能"""
    print(f"匿名ID: {get_anonymous_id()}")
    await report_user_count()


if __name__ == "__main__":
    asyncio.run(test_statistics())
