"""日结模块 Celery 任务"""
import logging
import datetime

from celery import shared_task
from django.utils import timezone

from .models import DailySettlementConfig, SettlementModuleEnum
from .services import (
    calculate_plate_order_daily_summary,
    calculate_printing_order_daily_summary,
)
from .signals import daily_settlement_completed

logger = logging.getLogger(__name__)


@shared_task(bind=True)
def run_daily_settlement(self):
    """
    执行所有商户的日结任务（固定时间触发）
    
    在 settings.py 中配置的固定时间触发，
    拉取所有配置了统计模块的商户，逐个执行日结。
    """
    from basic_info.models import Merchant
    
    # 获取所有配置了统计模块的商户
    configs = DailySettlementConfig.objects.exclude(
        settlement_modules=[]
    ).select_related('merchant')
    
    logger.info(
        f'[settlement.tasks] 开始执行日结，共 {configs.count()} 个商户需要统计'
    )
    
    # 为每个商户触发日结任务
    for config in configs:
        settlement_date = timezone.localdate() - datetime.timedelta(days=1)
        run_merchant_daily_settlement.delay(
            merchant_id=config.merchant.id,
            settlement_date=str(settlement_date)
        )
    
    return {
        'task_id': self.request.id,
        'total_merchants': configs.count(),
        'settlement_date': str(timezone.localdate() - datetime.timedelta(days=1)),
    }


@shared_task(bind=True)
def run_merchant_daily_settlement(
    self,
    merchant_id: int,
    settlement_date: str | None = None
):
    """
    执行单个商户的日结
    
    Args:
        merchant_id: 商户ID
        settlement_date: 结算日期（YYYY-MM-DD），默认为昨天
    
    Returns:
        dict: 包含 task_id 和执行结果的 payload
    """
    from basic_info.models import Merchant
    
    # 解析日期
    if settlement_date:
        date_obj = datetime.datetime.strptime(settlement_date, '%Y-%m-%d').date()
    else:
        date_obj = timezone.localdate() - datetime.timedelta(days=1)
    
    merchant = Merchant.objects.get(id=merchant_id)
    config = merchant.settlement_config
    
    modules = config.settlement_modules
    summaries = {}
    errors = {}
    overall_status = 'success'
    
    logger.info(
        f'[settlement.tasks] 开始执行商户 {merchant_id} 的日结，'
        f'日期={date_obj}, 模块={modules}'
    )
    
    # 执行各模块的统计
    for module in modules:
        try:
            if module == SettlementModuleEnum.PLATE_ORDER:
                summary = calculate_plate_order_daily_summary(
                    merchant_id=merchant_id,
                    settlement_date=date_obj
                )
                summaries['plate_order'] = summary
                
            elif module == SettlementModuleEnum.PRINTING_ORDER:
                summary = calculate_printing_order_daily_summary(
                    merchant_id=merchant_id,
                    settlement_date=date_obj
                )
                summaries['printing_order'] = summary
                
        except Exception as e:
            logger.exception(
                f'[settlement.tasks] 商户 {merchant_id} 的 {module} 统计失败: {e}'
            )
            errors[module] = str(e)
            overall_status = 'partial'
    
    # 如果所有模块都失败
    if len(errors) == len(modules):
        overall_status = 'failed'
    
    # 发送信号（不包含统计结果详情）
    daily_settlement_completed.send(
        sender=run_merchant_daily_settlement,
        merchant=merchant,
        settlement_date=date_obj,
        status=overall_status,
        modules=modules,
        errors=errors,
        task_id=self.request.id
    )
    
    payload = {
        'task_id': self.request.id,
        'merchant_id': merchant_id,
        'settlement_date': str(date_obj),
        'status': overall_status,
        'modules': modules,
        'errors': errors,
    }
    
    logger.info(
        f'[settlement.tasks] 商户 {merchant_id} 日结完成: {payload}'
    )
    return payload
