"""
蜂鸟Pro 后台定时任务 v2.1
- 账号分析任务：定期从 Cursor API 获取账号用量数据
- 自动换号任务：检查用量超阈值的账号并自动换号
"""
import asyncio
import logging
from datetime import datetime, timedelta
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.interval import IntervalTrigger

from app.database import SessionLocal
from app.services import (
    AccountService, KeyService, GlobalSettingsService,
    analyze_account_from_token
)
from app.models.models import AccountStatus, KeyStatus, KeyMembershipType

# 配置日志
logger = logging.getLogger("tasks")
logger.setLevel(logging.INFO)

# 调度器
scheduler = AsyncIOScheduler()


async def analyze_accounts_task():
    """
    账号分析任务
    定期扫描 pending/available 状态的账号，从 Cursor API 获取最新用量数据

    执行频率：每 5 分钟
    """
    db = SessionLocal()
    try:
        # 检查开关
        enabled = GlobalSettingsService.get(db, "auto_analyze_enabled")
        if not enabled or str(enabled).strip().lower() not in ("true", "1", "yes", "y", "on"):
            logger.debug("[账号分析] 自动分析已关闭，跳过")
            return

        logger.info("[账号分析] 开始执行...")

        # 获取需要分析的账号
        accounts = AccountService.get_pending_accounts(db, limit=10)

        if not accounts:
            logger.info("[账号分析] 无需分析的账号")
            return

        logger.info(f"[账号分析] 发现 {len(accounts)} 个待分析账号")

        success_count = 0
        fail_count = 0

        for account in accounts:
            try:
                # 调用 Cursor API 分析账号
                analysis_data = await analyze_account_from_token(account.token)

                # 更新账号信息
                AccountService.update_from_analysis(db, account.id, analysis_data)

                if analysis_data.get("success"):
                    success_count += 1
                    logger.info(
                        f"[账号分析] {account.email} 分析成功: "
                        f"类型={analysis_data.get('account_type')}, "
                        f"用量={analysis_data.get('usage_percent')}%"
                    )
                else:
                    fail_count += 1
                    logger.warning(
                        f"[账号分析] {account.email} 分析失败: {analysis_data.get('error')}"
                    )

                # 避免请求过于频繁
                await asyncio.sleep(1)

            except Exception as e:
                fail_count += 1
                logger.error(f"[账号分析] {account.email} 异常: {str(e)}")

        logger.info(f"[账号分析] 完成: 成功 {success_count}, 失败 {fail_count}")

    except Exception as e:
        logger.error(f"[账号分析] 任务异常: {str(e)}")
    finally:
        db.close()


async def auto_switch_task():
    """
    自动换号任务
    检查已启用无感换号的密钥，如果当前账号用量超阈值则自动换号

    执行频率：每 10 分钟
    """
    db = SessionLocal()
    try:
        # 检查开关
        enabled = GlobalSettingsService.get(db, "auto_switch_enabled")
        if not enabled or str(enabled).strip().lower() not in ("true", "1", "yes", "y", "on"):
            logger.debug("[自动换号] 自动换号已关闭，跳过")
            return

        logger.info("[自动换号] 开始执行...")

        # 获取阈值设置
        auto_threshold = GlobalSettingsService.get_int(db, "auto_switch_threshold") or 98
        pro_threshold = GlobalSettingsService.get_int(db, "pro_switch_threshold") or 98

        # 查找已启用无感的活跃密钥
        from app.models.models import ActivationKey, CursorAccount

        active_keys = db.query(ActivationKey).filter(
            ActivationKey.status == KeyStatus.ACTIVE,
            ActivationKey.seamless_enabled == True,
            ActivationKey.current_account_id != None,
            ActivationKey.master_key_id == None  # 只处理主密钥
        ).all()

        if not active_keys:
            logger.info("[自动换号] 无需处理的密钥")
            return

        logger.info(f"[自动换号] 检查 {len(active_keys)} 个密钥")

        switch_count = 0

        for key in active_keys:
            try:
                # 获取当前账号
                account = AccountService.get_by_id(db, key.current_account_id)
                if not account:
                    continue

                # 确定阈值
                threshold = auto_threshold if key.membership_type == KeyMembershipType.AUTO else pro_threshold

                # 检查是否需要换号
                usage_percent = float(account.usage_percent) if account.usage_percent else 0
                if usage_percent < threshold:
                    continue

                logger.info(
                    f"[自动换号] 密钥 {key.key[:8]}**** 账号 {account.email} "
                    f"用量 {usage_percent}% >= {threshold}%, 触发换号"
                )

                # 执行换号
                success, message, new_account = KeyService.switch_account(db, key)

                if success:
                    switch_count += 1
                    logger.info(
                        f"[自动换号] 换号成功: {account.email} -> {new_account.email}"
                    )

                    # 记录日志
                    from app.services import LogService
                    LogService.log(
                        db, key.id, "auto_switch",
                        account_id=new_account.id,
                        success=True,
                        message=f"自动换号: {account.email} -> {new_account.email}",
                        usage_snapshot={
                            "old_account": account.to_dict(),
                            "new_account": new_account.to_dict(),
                            "trigger_usage_percent": usage_percent,
                            "threshold": threshold
                        }
                    )
                else:
                    logger.warning(f"[自动换号] 换号失败: {message}")

            except Exception as e:
                logger.error(f"[自动换号] 密钥 {key.key[:8]}**** 处理异常: {str(e)}")

        logger.info(f"[自动换号] 完成: 换号 {switch_count} 次")

    except Exception as e:
        logger.error(f"[自动换号] 任务异常: {str(e)}")
    finally:
        db.close()


async def cleanup_expired_keys_task():
    """
    清理过期密钥任务
    将过期的密钥状态更新为 expired，释放关联的账号

    执行频率：每小时
    """
    db = SessionLocal()
    try:
        logger.info("[清理过期] 开始执行...")

        from app.models.models import ActivationKey

        # 查找需要检查的活跃密钥
        active_keys = db.query(ActivationKey).filter(
            ActivationKey.status == KeyStatus.ACTIVE
        ).all()

        expired_count = 0

        for key in active_keys:
            if key.is_expired:
                # 释放账号
                if key.current_account_id:
                    account = AccountService.get_by_id(db, key.current_account_id)
                    if account:
                        AccountService.release_account(db, account)

                # 更新状态
                key.status = KeyStatus.EXPIRED
                key.seamless_enabled = False
                key.current_account_id = None
                db.commit()

                expired_count += 1
                logger.info(f"[清理过期] 密钥 {key.key[:8]}**** 已过期")

        logger.info(f"[清理过期] 完成: 处理 {expired_count} 个过期密钥")

    except Exception as e:
        logger.error(f"[清理过期] 任务异常: {str(e)}")
    finally:
        db.close()


async def init_global_settings_task():
    """
    初始化全局设置任务
    确保所有默认设置都存在

    执行频率：启动时执行一次
    """
    db = SessionLocal()
    try:
        logger.info("[初始化设置] 开始执行...")
        GlobalSettingsService.init_settings(db)
        logger.info("[初始化设置] 完成")
    except Exception as e:
        logger.error(f"[初始化设置] 任务异常: {str(e)}")
    finally:
        db.close()


def start_scheduler():
    """启动调度器"""
    # 添加定时任务
    scheduler.add_job(
        analyze_accounts_task,
        trigger=IntervalTrigger(minutes=5),
        id="analyze_accounts",
        name="账号分析任务",
        replace_existing=True
    )

    scheduler.add_job(
        auto_switch_task,
        trigger=IntervalTrigger(minutes=10),
        id="auto_switch",
        name="自动换号任务",
        replace_existing=True
    )

    scheduler.add_job(
        cleanup_expired_keys_task,
        trigger=IntervalTrigger(hours=1),
        id="cleanup_expired",
        name="清理过期密钥任务",
        replace_existing=True
    )

    # 启动调度器
    scheduler.start()
    logger.info("[调度器] 后台任务调度器已启动")


def stop_scheduler():
    """停止调度器"""
    if scheduler.running:
        scheduler.shutdown()
        logger.info("[调度器] 后台任务调度器已停止")


async def run_startup_tasks():
    """运行启动任务"""
    await init_global_settings_task()
    # 启动后立即执行一次账号分析
    await analyze_accounts_task()
