"""清理龙先生重复/无 pem 证书俱乐部。

规则：
- 候选：club_id=lsx / 名称含「龙先生」 / wx_appid=龙先生小程序
- 「有 pem」：pay_key_path / pay_cert_path / private_key_path 任一路径以 .pem 结尾
  （你后台上传的证书路径都是 *.pem；脚本自动建的/空配置通常没有）
- 「可删」：上述三个字段都没有以 .pem 结尾的路径
- 默认 dry-run；--apply 才删除
- 若候选里没有任何「有 pem」的对照，默认不删；加 --force-delete-empty-only 才删

用法：
  python manage.py cleanup_lsx_empty_club
  python manage.py cleanup_lsx_empty_club --apply
  python manage.py cleanup_lsx_empty_club --apply --remove-seed-users
"""
from django.core.management.base import BaseCommand
from django.db import transaction
from django.db.models import Q

from jituan.models import (
    Club,
    ClubDashouExamConfig,
    ClubDashouExamPass,
    ClubDashouExamQuestion,
    ClubDashouExamQuestionImage,
    ClubFadanFenhongLilv,
    ClubHuiyuanBundleInclude,
    ClubHuiyuanPrice,
    ClubKaoheChenghaoConfig,
    ClubLilubiao,
    ClubPaymentChannel,
    ClubShangpinLeixingConfig,
    ClubTixianQuota,
    ClubWithdrawConfig,
)
from users.business_models import User
from users.models import UserBoss, UserGuanshi, UserZuzhang

LSX_APPID = 'wx7ff90e9d024fcdb8'
SEED_UIDS = ('9910001', '9910002')

RELATED_MODELS = (
    ClubPaymentChannel,
    ClubHuiyuanPrice,
    ClubHuiyuanBundleInclude,
    ClubLilubiao,
    ClubWithdrawConfig,
    ClubTixianQuota,
    ClubShangpinLeixingConfig,
    ClubKaoheChenghaoConfig,
    ClubFadanFenhongLilv,
    ClubDashouExamConfig,
    ClubDashouExamQuestion,
    ClubDashouExamQuestionImage,
    ClubDashouExamPass,
)

# 证书「文件」字段（应以 .pem 结尾）；platform_cert_dir 是目录，不参与判定
_PEM_FILE_FIELDS = ('pay_key_path', 'pay_cert_path', 'private_key_path')


def _path_ends_with_pem(path):
    return str(path or '').strip().lower().endswith('.pem')


def _has_pem_paths(club):
    """后台上传过证书：路径以 .pem 结尾。"""
    return any(_path_ends_with_pem(getattr(club, f, '')) for f in _PEM_FILE_FIELDS)


def _pem_field_summary(club):
    lines = []
    for f in _PEM_FILE_FIELDS:
        val = (getattr(club, f, '') or '').strip()
        if not val:
            tag = '空'
        elif _path_ends_with_pem(val):
            tag = 'pem✓'
        else:
            tag = '非pem✗'
        lines.append(f'{f}={val or "(空)"} [{tag}]')
    plat = (getattr(club, 'platform_cert_dir', '') or '').strip()
    lines.append(f'platform_cert_dir={plat or "(空)"} [目录仅展示]')
    return lines


def _candidates():
    return Club.query.filter(
        Q(club_id__iexact='lsx')
        | Q(club_id__icontains='lsx')
        | Q(name__icontains='龙先生')
        | Q(wx_appid=LSX_APPID)
    ).order_by('club_id')


def _purge_club_related(club_id, stdout, style):
    for model in RELATED_MODELS:
        try:
            n = model.query.filter(club_id=club_id).count()
            if n:
                model.query.filter(club_id=club_id).delete()
                stdout.write(f'  - 已删 {model.__name__} x{n}')
        except Exception as exc:
            stdout.write(style.WARNING(f'  - 跳过 {model.__name__}: {exc}'))


class Command(BaseCommand):
    help = '列出并删除龙先生相关「证书路径不以 .pem 结尾」的重复俱乐部（默认 dry-run）'

    def add_arguments(self, parser):
        parser.add_argument('--apply', action='store_true', help='真正写入删除')
        parser.add_argument(
            '--force-delete-empty-only',
            action='store_true',
            help='即使没有「有 .pem」的对照俱乐部，也允许删除非 pem 候选',
        )
        parser.add_argument(
            '--remove-seed-users',
            action='store_true',
            help='同时删除 seed_lsx_invite_data 种子用户 9910001/9910002',
        )
        parser.add_argument(
            '--club-id',
            type=str,
            default='',
            help='只处理指定 club_id（精确匹配）',
        )

    def handle(self, *args, **options):
        apply = bool(options.get('apply'))
        force = bool(options.get('force_delete_empty_only'))
        only_id = (options.get('club_id') or '').strip()

        qs = _candidates()
        if only_id:
            qs = Club.query.filter(club_id=only_id)

        clubs = list(qs)
        if not clubs:
            self.stdout.write(self.style.WARNING('未找到龙先生/lsx 相关俱乐部'))
            return

        with_pem = []
        without_pem = []
        self.stdout.write(self.style.SUCCESS('=' * 60))
        self.stdout.write('判定标准：pay_key_path / pay_cert_path / private_key_path 是否以 .pem 结尾')
        self.stdout.write('龙先生相关俱乐部扫描结果：')
        for c in clubs:
            keyed = _has_pem_paths(c)
            (with_pem if keyed else without_pem).append(c)
            self.stdout.write('-' * 40)
            self.stdout.write(f'club_id={c.club_id}  name={c.name}  status={c.status}')
            self.stdout.write(f'  wx_appid={c.wx_appid or "(空)"}')
            for line in _pem_field_summary(c):
                self.stdout.write(f'  {line}')
            self.stdout.write(
                f'  >>> {"有 .pem 路径（保留）" if keyed else "无 .pem 路径（可删）"}'
            )

        self.stdout.write(self.style.SUCCESS('=' * 60))
        self.stdout.write(f'有 .pem: {len(with_pem)} 条；无 .pem: {len(without_pem)} 条')

        if not without_pem:
            self.stdout.write(self.style.SUCCESS('没有「无 .pem 路径」的俱乐部，无需删除。'))
        elif not with_pem and not force:
            self.stdout.write(self.style.ERROR(
                '全部候选都没有 .pem 路径。为安全起见不自动删。'
                '若确认要删，加 --force-delete-empty-only --apply'
            ))
        else:
            for c in without_pem:
                self.stdout.write(self.style.WARNING(
                    f'将删除无 .pem 俱乐部: {c.club_id} ({c.name})'
                ))
                if not apply:
                    self.stdout.write('  (dry-run，未真正删除；加 --apply 执行)')
                    continue
                with transaction.atomic():
                    _purge_club_related(c.club_id, self.stdout, self.style)
                    Club.query.filter(club_id=c.club_id).delete()
                self.stdout.write(self.style.SUCCESS(f'  已删除俱乐部 {c.club_id}'))

        if options.get('remove_seed_users'):
            self.stdout.write('-' * 40)
            self.stdout.write('处理种子用户 9910001 / 9910002 ...')
            for uid in SEED_UIDS:
                user = User.query.filter(UserUID=uid).first()
                if not user:
                    self.stdout.write(f'  {uid}: 不存在')
                    continue
                self.stdout.write(
                    f'  {uid}: ClubID={user.ClubID} Phone={user.Phone} OpenID={user.OpenID}'
                )
                if not apply:
                    self.stdout.write('  (dry-run)')
                    continue
                with transaction.atomic():
                    UserZuzhang.query.filter(user=user).delete()
                    UserGuanshi.query.filter(user=user).delete()
                    UserBoss.query.filter(user=user).delete()
                    user.delete()
                self.stdout.write(self.style.SUCCESS(f'  已删除用户 {uid}'))

        if not apply:
            self.stdout.write(self.style.WARNING(
                '\n当前为预览。确认后执行：\n'
                '  python manage.py cleanup_lsx_empty_club --apply\n'
                '如需顺带删种子账号：\n'
                '  python manage.py cleanup_lsx_empty_club --apply --remove-seed-users'
            ))
