"""
收回因 dddhq 每次 sync 错误补开通的会员权益（保守策略，优先不误伤正常付费）。

安全规则（按优先级）：
1. 有任意未过期已付充值单支撑 → 绝不收回
2. 无充值单的老数据 → 不自动处理
3. 默认要求符合 bug repair 指纹（UpdateTime 写回 + 旧单原定期限已过）
4. 后台减会员：仅当仍有效且无未过期充值单时才 revoke

用法：
  python manage.py rollback_erroneous_member_restore --dry-run
  python manage.py rollback_erroneous_member_restore
  python manage.py rollback_erroneous_member_restore --since 2026-06-01
"""
from django.core.management.base import BaseCommand
from django.db import transaction

from jituan.services.huiyuan_bundle import huiyuan_ids_match
from jituan.services.member_recharge import (
    expire_huiyuangoumai_record,
    revoke_member_entitlement_admin,
    should_rollback_erroneous_membership,
    user_has_active_czjilu_entitlement,
)
from products.models import Huiyuangoumai
from users.models import Xiugaijilu


class Command(BaseCommand):
    help = '收回错误恢复的会员（保守：有未过期充值单绝不碰）'

    def add_arguments(self, parser):
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='仅统计，不写库',
        )
        parser.add_argument(
            '--since',
            default='2026-06-01',
            help='repair 指纹 UpdateTime 起始日（默认 2026-06-01）',
        )
        parser.add_argument(
            '--no-repair-signature',
            action='store_true',
            help='不要求 repair 指纹（更激进，不推荐）',
        )

    def handle(self, *args, **options):
        dry_run = bool(options.get('dry_run'))
        since = options.get('since')
        require_sig = not bool(options.get('no_repair_signature'))
        admin_revoke = 0
        expire_orphan = 0
        skipped_safe = 0
        samples = []

        with transaction.atomic():
            seen_pairs = set()
            logs = Xiugaijilu.query.filter(
                huiyuan_id__isnull=False,
            ).exclude(huiyuan_id='').order_by('-CreateTime')

            for log in logs:
                note = log.qitashuoming or ''
                if '移除' not in note and '减会员' not in note:
                    continue
                if not log.yonghuid or not log.huiyuan_id:
                    continue
                pair = (log.yonghuid, str(log.huiyuan_id).strip())
                if pair in seen_pairs:
                    continue
                seen_pairs.add(pair)

                for rec in Huiyuangoumai.query.filter(yonghu_id=log.yonghuid):
                    if not huiyuan_ids_match(rec.huiyuan_id, log.huiyuan_id):
                        continue
                    if rec.jiance_shifou_daoqi() or rec.huiyuan_zhuangtai != 1:
                        continue
                    if user_has_active_czjilu_entitlement(
                        rec.yonghu_id, rec.huiyuan_id, rec.club_id,
                    ):
                        skipped_safe += 1
                        continue
                    ok, detail = should_rollback_erroneous_membership(
                        rec, since=since, require_repair_signature=require_sig,
                    )
                    if not ok:
                        skipped_safe += 1
                        continue

                    admin_revoke += 1
                    samples.append(
                        f'[后台已减仍有效] {log.yonghuid} 会员{log.huiyuan_id} '
                        f'依据单{detail or "-"}',
                    )
                    if not dry_run:
                        revoke_member_entitlement_admin(log.yonghuid, log.huiyuan_id)
                    break

            for rec in Huiyuangoumai.query.filter(huiyuan_zhuangtai=1):
                if rec.jiance_shifou_daoqi():
                    continue
                ok, detail = should_rollback_erroneous_membership(
                    rec, since=since, require_repair_signature=require_sig,
                )
                if not ok:
                    if detail == '有未过期充值单支撑':
                        skipped_safe += 1
                    continue

                expire_orphan += 1
                samples.append(
                    f'[充值单已过期仍有效] {rec.yonghu_id} 会员{rec.huiyuan_id} '
                    f'到期{rec.daoqi_time} 依据单{detail or "-"}',
                )
                if not dry_run:
                    expire_huiyuangoumai_record(
                        rec,
                        reason='rollback_erroneous_member_restore',
                    )

            if dry_run:
                transaction.set_rollback(True)

        mode = 'DRY-RUN' if dry_run else 'APPLIED'
        self.stdout.write(self.style.SUCCESS(
            f'[{mode}] 后台减会员仍有效收回 {admin_revoke} 条；'
            f'无有效充值单支撑过期 {expire_orphan} 条；'
            f'安全跳过 {skipped_safe} 条（含正常付费/不符合指纹）',
        ))
        if require_sig:
            self.stdout.write('  已启用 repair 指纹校验（推荐）')
        else:
            self.stdout.write(self.style.WARNING('  未启用 repair 指纹（激进模式，慎用）'))
        for line in samples[:50]:
            self.stdout.write(f'  {line}')
        if len(samples) > 50:
            self.stdout.write(f'  ... 另有 {len(samples) - 50} 条')
