"""
【反向撤销】repair_wechat_income 造成的重复记账。

你当时执行的指令是：
  python manage.py repair_wechat_income
或：
  python manage.py repair_wechat_income --date 2026-06-24 --days 7

repair 逻辑：按「当日创建的已支付订单/充值单」逐条 +金额、+笔数、写 platform_income_log、加 szjilu。
本命令用完全相同扫描列表，逐条反向 -金额、-笔数、删日志、减 szjilu。

用法：
  1. 预览（不改库）：
     python manage.py undo_repair_wechat_income

  2. 确认后撤销（加多少减多少）：
     python manage.py undo_repair_wechat_income --yes

  3. 若当时带了参数，必须一致：
     python manage.py undo_repair_wechat_income --date 2026-06-01 --days 30 --run-date 2026-06-24 --yes
     （--run-date = 你执行 repair 那天，默认今天）

  4. 全部清零（恢复到 0）：
     python manage.py undo_repair_wechat_income --zero-all --yes
"""
from datetime import date, timedelta

from django.core.management.base import BaseCommand
from django.db.models import Sum

from config.models import DailyIncomeStat
from jituan.services.szjilu_accounting import (
    undo_repair_wechat_income_period,
    zero_all_income_statistics,
)


class Command(BaseCommand):
    help = '反向撤销 repair_wechat_income 造成的收支重复记账'

    def add_arguments(self, parser):
        parser.add_argument(
            '--date', type=str, default='',
            help='与 repair 相同的 --date（扫描区间结束日），默认今天',
        )
        parser.add_argument(
            '--days', type=int, default=1,
            help='与 repair 相同的 --days，默认 1',
        )
        parser.add_argument(
            '--run-date', type=str, default='',
            help='你执行 repair 的日期（金额被记到哪天的 daily），默认今天',
        )
        parser.add_argument('--yes', action='store_true', help='确认执行')
        parser.add_argument(
            '--zero-all', action='store_true',
            help='收支统计全部清零（日收入、日志、szjilu 收入流水归零）',
        )

    def handle(self, *args, **options):
        if options['zero_all']:
            self._zero_all(not options['yes'])
            return

        if options['date']:
            end_day = date.fromisoformat(options['date'])
        else:
            end_day = date.today()
        days = max(1, int(options['days'] or 1))
        start_day = end_day - timedelta(days=days - 1)
        if options['run_date']:
            inflation_date = date.fromisoformat(options['run_date'])
        else:
            inflation_date = date.today()

        dry_run = not options['yes']

        self.stdout.write(self.style.WARNING(
            '========== 反向撤销 repair_wechat_income ==========\n'
            f'原 repair 扫描区间: {start_day} ~ {end_day} （--days {days}）\n'
            f'金额被记到日统计日期: {inflation_date} （--run-date）\n'
        ))

        if dry_run:
            self.stdout.write('【预览】未改数据库\n')
        else:
            self.stdout.write('【执行】正在反向扣减...\n')

        r = undo_repair_wechat_income_period(
            start_day, end_day, inflation_date, dry_run=dry_run,
        )

        self.stdout.write(f'  将撤销条数: {r["undo_count"]} 条')
        self.stdout.write(f'  将扣减金额: {r["undo_amount"]:.2f} 元')
        self.stdout.write(
            f'  执行前 {inflation_date} 日统计: {r["before_daily_on_inflation_date"]:.2f} 元'
        )

        if r['items']:
            self.stdout.write('  明细:')
            for ref, cid, amt, kind in r['items']:
                self.stdout.write(f'    - {ref}  {amt}元  club={cid}  ({kind})')

        if not dry_run:
            self.stdout.write(self.style.SUCCESS(
                f'\n执行后 {inflation_date} 日统计: {r.get("after_daily_on_inflation_date", 0):.2f} 元'
            ))
            self.stdout.write(self.style.SUCCESS('反向撤销完成，请刷新后台财务页。'))
        else:
            self.stdout.write(self.style.WARNING(
                '\n预览完成。确认后执行（参数与 repair 保持一致）：\n'
                f'  python manage.py undo_repair_wechat_income --date {end_day} --days {days} '
                f'--run-date {inflation_date} --yes\n'
                '全部清零：\n'
                '  python manage.py undo_repair_wechat_income --zero-all --yes'
            ))

    def _zero_all(self, dry_run):
        agg = DailyIncomeStat.objects.aggregate(amt=Sum('total_amount'), cnt=Sum('total_count'))
        self.stdout.write(self.style.ERROR(
            '========== 收支统计全部清零 ==========\n'
            f'当前 daily_income_stat 合计: {float(agg["amt"] or 0):.2f} 元 / {int(agg["cnt"] or 0)} 笔\n'
            '将删除: platform_income_log 全部、daily_income_stat 全部\n'
            '将归零: szjilu.TotalIncome / TotalFlow / DailyFlow\n'
        ))
        if dry_run:
            self.stdout.write(self.style.WARNING(
                '预览。确认清零：\n'
                '  python manage.py undo_repair_wechat_income --zero-all --yes'
            ))
            return
        zero_all_income_statistics()
        self.stdout.write(self.style.SUCCESS('已全部清零。请刷新后台。'))
