"""
手动触发日结任务（management command）

用法：
    python manage.py run_daily_settlement

选项：
    --merchant-id: 仅处理指定商户ID
    --date: 指定结算日期（YYYY-MM-DD），默认为昨天
    --sync: 同步执行（阻塞），默认为异步（通过 Celery）
"""

from datetime import datetime

from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
from django.utils import timezone

from settlement.models import DailySettlementConfig


class Command(BaseCommand):
    help = '手动触发日结任务（支持指定商户、日期、同步/异步执行）'

    def add_arguments(self, parser):
        parser.add_argument(
            '--merchant-id',
            type=int,
            help='仅处理指定商户ID',
        )
        parser.add_argument(
            '--date',
            type=str,
            help='指定结算日期（YYYY-MM-DD），默认为昨天',
        )
        parser.add_argument(
            '--sync',
            action='store_true',
            help='同步执行（阻塞），默认为异步（通过 Celery）',
        )

    def handle(self, *args, **options):
        from settlement.tasks import run_daily_settlement, run_merchant_daily_settlement

        merchant_id = options.get('merchant_id')
        date_str = options.get('date')
        sync_mode = bool(options['sync'])

        # 解析日期
        if date_str:
            try:
                date_obj = datetime.strptime(date_str, '%Y-%m-%d').date()
            except ValueError as e:
                raise CommandError(f'--date 必须为 YYYY-MM-DD 格式: {e}')
        else:
            date_obj = timezone.localdate() - timezone.timedelta(days=1)

        self.stdout.write(f'[日结] 开始执行: 日期={date_obj}, 同步模式={sync_mode}')

        if merchant_id:
            # 处理单个商户
            self._handle_single_merchant(
                merchant_id=merchant_id,
                date_obj=date_obj,
                sync_mode=sync_mode
            )
        else:
            # 处理所有商户
            self._handle_all_merchants(
                date_obj=date_obj,
                sync_mode=sync_mode
            )

    def _handle_single_merchant(self, merchant_id: int, date_obj, sync_mode: bool):
        """处理单个商户的日结"""
        from settlement.tasks import run_merchant_daily_settlement

        try:
            config = DailySettlementConfig.objects.select_related('merchant').get(
                merchant_id=merchant_id
            )
        except DailySettlementConfig.DoesNotExist:
            self.stderr.write(
                self.style.ERROR(
                    f'商户 {merchant_id} 未配置日结，跳过'
                )
            )
            return

        if not config.settlement_modules:
            self.stdout.write(
                f'商户 {config.merchant.name} (ID={merchant_id}) 未配置统计模块，跳过'
            )
            return

        self.stdout.write(
            f'处理商户: {config.merchant.name} (ID={merchant_id}), '
            f'模块={config.settlement_modules}'
        )

        if sync_mode:
            # 同步执行
            result = run_merchant_daily_settlement(
                merchant_id=merchant_id,
                settlement_date=str(date_obj)
            )
            self.stdout.write(
                self.style.SUCCESS(
                    f'商户 {merchant_id} 日结完成: {result}'
                )
            )
        else:
            # 异步执行（通过 Celery）
            task = run_merchant_daily_settlement.delay(
                merchant_id=merchant_id,
                settlement_date=str(date_obj)
            )
            self.stdout.write(
                f'商户 {merchant_id} 日结任务已提交: task_id={task.id}'
            )

    def _handle_all_merchants(self, date_obj, sync_mode: bool):
        """处理所有商户的日结"""
        from settlement.tasks import run_daily_settlement

        configs = DailySettlementConfig.objects.filter(
            settlement_modules__len__gt=0
        ).select_related('merchant')

        if not configs.exists():
            self.stdout.write('没有配置日结的商户，跳过')
            return

        self.stdout.write(
            f'共 {configs.count()} 个商户需要执行日结'
        )

        if sync_mode:
            # 同步执行（逐个商户）
            for config in configs:
                self._handle_single_merchant(
                    merchant_id=config.merchant.id,
                    date_obj=date_obj,
                    sync_mode=True
                )
        else:
            # 异步执行（通过 Celery）
            task = run_daily_settlement.delay()
            self.stdout.write(
                f'所有商户日结任务已提交: task_id={task.id}'
            )
