# -*- coding: utf-8 -*-
"""
龙先生(lxs)审核目录重置为「娱乐陪伴」正向内容（非代练代打、不过度游戏化）。

针对：全局 3 个 shenhezhuangtai=2 的商品类型 + 俱乐部 lxs 下专区/商品。

动作：
  1) 将 3 个审核类型名改为：娱乐陪伴 / 休闲同行 / 友好互动（改全局类型名，dry-run 会提示）
  2) 清空 lxs 下这些类型的审核专区+商品（只删 DB，不删 OSS）
  3) 每个类型建 2 个专区；每个专区 10 个商品（共 60）
  4) 图标一律 a_long/morentouxiang.jpg
  5) 文案纯正能量陪伴/交流，禁止代练代打上分等词

用法:
  python manage.py reset_lxs_shenhe_yule_peiban
  python manage.py reset_lxs_shenhe_yule_peiban --list
  python manage.py reset_lxs_shenhe_yule_peiban --apply --i-confirm=lxs-yule-peiban
"""
from __future__ import annotations

from decimal import Decimal

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

ALLOWED_CLUB_ID = 'lxs'
NAME_HINT = '龙先生'
SHENHE = 2
DEFAULT_AVATAR = 'a_long/morentouxiang.jpg'
CONFIRM_TOKEN = 'lxs-yule-peiban'
EXPECTED_TYPE_COUNT = 3

# 三个审核类型目标名称（按现有审核类型 id 升序一一对应）
TYPE_NAMES = ['娱乐陪伴', '休闲同行', '友好互动']

# 每个类型 2 个专区名
ZONE_NAMES_BY_TYPE = [
    ['温暖陪伴', '轻松畅聊'],
    ['兴趣交流', '日常鼓励'],
    ['正能量同行', '休闲时光'],
]

# 每个专区 10 个商品：(标题, 介绍, 价格)
# 刻意弱化具体竞技/上分，强调陪伴、交流、正向娱乐
PRODUCTS_PER_ZONE = [
    [
        ('暖心语音陪伴', '友好语音交流，倾听分享，营造轻松正能量氛围。', '19.90'),
        ('轻松心情疏导', '温和聊天陪伴，帮助放松心情，传递积极态度。', '19.90'),
        ('兴趣话题畅聊', '围绕健康兴趣爱好交流，互相启发，气氛友善。', '15.90'),
        ('正能量晚间陪伴', '晚间轻松聊天，分享日常点滴，友好互动。', '19.90'),
        ('学习打卡互勉', '互相提醒学习计划，鼓励坚持，共同进步。', '15.90'),
        ('运动打卡陪伴', '交流运动习惯与打卡心得，互相鼓励坚持。', '15.90'),
        ('阅读心得分享', '分享好书与阅读感受，文明交流，开阔视野。', '12.90'),
        ('音乐放松同行', '一起听歌聊天放松，分享喜爱曲目，气氛轻松。', '12.90'),
        ('生活小妙招交流', '交流生活经验与小技巧，互助友爱。', '12.90'),
        ('周末休闲畅聊', '周末轻松闲聊，分享愉快见闻，友好陪伴。', '15.90'),
    ],
    [
        ('兴趣社群式交流', '按兴趣轻松交流，结识同好，氛围文明友好。', '15.90'),
        ('手工创作分享', '分享手工与创作过程，互相欣赏鼓励。', '15.90'),
        ('摄影见闻交流', '交流摄影与风景见闻，传递美好感受。', '12.90'),
        ('厨艺心得闲聊', '聊聊家常菜与烹饪心得，轻松愉快。', '12.90'),
        ('宠物日常分享', '分享萌宠日常，友好互动，温暖治愈。', '12.90'),
        ('旅行见闻讲述', '讲述旅行见闻与风景，开阔眼界，正能量满满。', '19.90'),
        ('电影观后闲谈', '交流观影感受与推荐，文明讨论，轻松愉快。', '12.90'),
        ('桌游规则解说', '友好讲解休闲桌游玩法，一起快乐体验。', '15.90'),
        ('棋类休闲对弈', '休闲棋类友好对弈，重在交流与乐趣。', '15.90'),
        ('午后茶歇闲聊', '午后轻松聊天陪伴，舒缓节奏，气氛温馨。', '12.90'),
    ],
    [
        ('早安鼓励打卡', '清晨互相问候鼓励，开启积极一天。', '9.90'),
        ('习惯养成互勉', '一起制定小目标，互相督促，温柔坚持。', '15.90'),
        ('情绪友好倾听', '认真倾听烦恼，给予友善支持与正向建议。', '19.90'),
        ('时间管理小谈', '交流高效作息小方法，互相提醒，积极向上。', '15.90'),
        ('环保生活分享', '分享绿色生活小习惯，传递责任与温暖。', '9.90'),
        ('志愿服务见闻', '交流公益与志愿服务见闻，弘扬正能量。', '12.90'),
        ('亲子沟通小贴士', '交流亲子相处经验，友善互助（非医疗建议）。', '15.90'),
        ('职场礼仪闲谈', '聊聊职场沟通礼仪与礼貌习惯，积极文明。', '15.90'),
        ('节日祝福陪伴', '节日期间友好问候与陪伴聊天，传递祝福。', '12.90'),
        ('睡前放松畅聊', '睡前轻松聊天，帮助放松，友好结束一天。', '15.90'),
    ],
]

BANNED_WORDS = (
    '代练', '代打', '上分', '上段', '包星', '定位赛', '代肝',
    '代刷', '代打手', '代练平台', '代练服务', '护航上分',
)


class Command(BaseCommand):
    help = '龙先生审核类型改为娱乐陪伴并向 lxs 写入正能量专区/商品（默认 dry-run）'

    def add_arguments(self, parser):
        parser.add_argument('--apply', action='store_true', help='真正写库')
        parser.add_argument(
            '--i-confirm',
            type=str,
            default='',
            help=f'必须等于 {CONFIRM_TOKEN} 才允许 --apply',
        )
        parser.add_argument(
            '--list',
            action='store_true',
            help='只列出当前审核类型及 lxs 存量',
        )
        parser.add_argument(
            '--skip-rename-types',
            action='store_true',
            help='不修改全局审核类型名称，仅重建 lxs 专区/商品',
        )

    def handle(self, *args, **options):
        from jituan.models import Club
        from products.models import Shangpin, ShangpinLeixing, ShangpinZhuanqu

        apply = bool(options.get('apply'))
        confirm = (options.get('i_confirm') or '').strip()
        skip_rename = bool(options.get('skip_rename_types'))

        club = Club.query.filter(club_id=ALLOWED_CLUB_ID).first()
        if not club:
            raise CommandError(f'俱乐部 {ALLOWED_CLUB_ID} 不存在')
        if NAME_HINT not in (club.name or ''):
            raise CommandError(
                f'安全拦截：{ALLOWED_CLUB_ID} name={club.name!r} 不含「{NAME_HINT}」'
            )

        audit_types = list(
            ShangpinLeixing.query.filter(shenhezhuangtai=SHENHE).order_by('id')
        )
        if len(audit_types) != EXPECTED_TYPE_COUNT:
            raise CommandError(
                f'安全拦截：审核类型数量应为 {EXPECTED_TYPE_COUNT}，'
                f'当前为 {len(audit_types)}：'
                + ', '.join(f'id={t.id}「{t.jieshao}」' for t in audit_types)
            )

        leixing_ids = [t.id for t in audit_types]

        def counts():
            z = ShangpinZhuanqu.query.filter(
                club_id=ALLOWED_CLUB_ID,
                leixing_id__in=leixing_ids,
                shenhezhuangtai=SHENHE,
                dianpu__isnull=True,
            ).count()
            p = Shangpin.query.filter(
                club_id=ALLOWED_CLUB_ID,
                leixing_id__in=leixing_ids,
                shenhezhuangtai=SHENHE,
                dianpu__isnull=True,
            ).count()
            return z, p

        if options.get('list'):
            self.stdout.write(self.style.NOTICE(
                f'审核类型 → 计划改名；lxs 当前专区/商品：'
            ))
            for i, t in enumerate(audit_types):
                z = ShangpinZhuanqu.query.filter(
                    club_id=ALLOWED_CLUB_ID, leixing_id=t.id,
                    shenhezhuangtai=SHENHE, dianpu__isnull=True,
                ).count()
                p = Shangpin.query.filter(
                    club_id=ALLOWED_CLUB_ID, leixing_id=t.id,
                    shenhezhuangtai=SHENHE, dianpu__isnull=True,
                ).count()
                self.stdout.write(
                    f'  id={t.id}「{t.jieshao}」→「{TYPE_NAMES[i]}」  '
                    f'lxs zones={z} products={p}'
                )
            return

        # 文案自检
        for zone_list in PRODUCTS_PER_ZONE:
            if len(zone_list) != 10:
                raise CommandError('内部错误：每个专区必须恰好 10 个商品')
            for title, intro, _price in zone_list:
                blob = title + intro
                for w in BANNED_WORDS:
                    if w in blob:
                        raise CommandError(f'文案含禁止词「{w}」: {title}')

        for zones in ZONE_NAMES_BY_TYPE:
            if len(zones) != 2:
                raise CommandError('内部错误：每个类型必须恰好 2 个专区')

        if apply and confirm != CONFIRM_TOKEN:
            raise CommandError(
                f'安全拦截：--apply 必须带 --i-confirm={CONFIRM_TOKEN}\n'
                f'  python manage.py reset_lxs_shenhe_yule_peiban '
                f'--apply --i-confirm={CONFIRM_TOKEN}'
            )

        old_z, old_p = counts()
        mode = 'APPLY' if apply else 'DRY-RUN'
        self.stdout.write(self.style.NOTICE(
            f'\n===== {mode} 龙先生审核 → 娱乐陪伴 =====\n'
            f'club={ALLOWED_CLUB_ID} ({club.name})\n'
            f'将清空 lxs 审核专区={old_z} 商品={old_p}，再写入 '
            f'{EXPECTED_TYPE_COUNT}类型×2专区×10商品=60\n'
            f'图标: {DEFAULT_AVATAR}\n'
            f'改名全局类型: {"否" if skip_rename else "是（影响所有俱乐部审核展示名）"}\n'
        ))

        self.stdout.write('—— 类型改名计划 ——')
        for i, t in enumerate(audit_types):
            self.stdout.write(f'  id={t.id}「{t.jieshao}」→「{TYPE_NAMES[i]}」')

        self.stdout.write('—— 专区/商品结构 ——')
        for i, tname in enumerate(TYPE_NAMES):
            for zn in ZONE_NAMES_BY_TYPE[i]:
                self.stdout.write(f'  「{tname}」/「{zn}」→ 10 个正能量商品')

        self.stdout.write('—— 商品样例 ——')
        for title, intro, price in PRODUCTS_PER_ZONE[0][:3]:
            self.stdout.write(f'  {title} ¥{price} | {intro}')

        if not apply:
            self.stdout.write(self.style.WARNING(
                '\n以上仅计划。确认后：\n'
                f'  python manage.py reset_lxs_shenhe_yule_peiban '
                f'--apply --i-confirm={CONFIRM_TOKEN}\n'
            ))
            return

        stats = {
            'types_renamed': 0,
            'deleted_products': 0,
            'deleted_zones': 0,
            'zones_created': 0,
            'products_created': 0,
        }

        with transaction.atomic():
            if not skip_rename:
                for i, t in enumerate(audit_types):
                    new_name = TYPE_NAMES[i]
                    if (t.jieshao or '') != new_name:
                        t.jieshao = new_name
                        t.tupian_url = t.tupian_url or DEFAULT_AVATAR
                        t.save()
                        stats['types_renamed'] += 1

            n_prod, _ = Shangpin.query.filter(
                club_id=ALLOWED_CLUB_ID,
                leixing_id__in=leixing_ids,
                shenhezhuangtai=SHENHE,
                dianpu__isnull=True,
            ).delete()
            n_zone, _ = ShangpinZhuanqu.query.filter(
                club_id=ALLOWED_CLUB_ID,
                leixing_id__in=leixing_ids,
                shenhezhuangtai=SHENHE,
                dianpu__isnull=True,
            ).delete()
            stats['deleted_products'] = n_prod
            stats['deleted_zones'] = n_zone

            # 按类型顺序重建
            for i, lx in enumerate(audit_types):
                # 刷新名称（若已 rename）
                lx = ShangpinLeixing.query.filter(id=lx.id).first()
                zone_names = ZONE_NAMES_BY_TYPE[i]
                # 两个专区共用同一组 10 商品模板？用户要每个专区 10 个 —
                # 使用 PRODUCTS_PER_ZONE[i] 作为该类型两专区的商品池，
                # 第一专区用全部 10 个；第二专区标题加专区后缀避免同类型下标题撞车，
                # 或两专区用同一文案但标题带专区名区分。
                base_products = PRODUCTS_PER_ZONE[i]
                for zi, zname in enumerate(zone_names):
                    zrow = ShangpinZhuanqu.query.create(
                        mingzi=zname,
                        leixing_id=lx.id,
                        club_id=ALLOWED_CLUB_ID,
                        tupian_url=DEFAULT_AVATAR,
                        shenhezhuangtai=SHENHE,
                        paixu=20 - zi * 10,
                        shangjia_zhuangtai=True,
                        fengjin_zhuangtai=True,
                        dianpu=None,
                        dianpu_leixing=None,
                    )
                    stats['zones_created'] += 1

                    for pi, (title, intro, price) in enumerate(base_products):
                        # 同类型不同专区：标题加专区名，避免去重冲突且语义清晰
                        full_title = f'{title}·{zname}'
                        for w in BANNED_WORDS:
                            if w in full_title or w in intro:
                                raise CommandError(f'禁止词命中: {full_title}')
                        Shangpin.query.create(
                            biaoqian=full_title[:45],
                            jiage=Decimal(price),
                            kucun=99999,
                            leixing_id=lx.id,
                            zhuanqu_id=zrow.id,
                            zhenshi_xiaoliang=0,
                            duiwai_xiaoliang=0,
                            jieshao=intro,
                            xiadan_xuzhi=(
                                '本服务为正向休闲陪伴与交流，请文明沟通。'
                                '禁止任何代练、代打或不正当行为。'
                            ),
                            guize_tupian='',
                            tupian_url=DEFAULT_AVATAR,
                            yaoqiuleixing=lx.yaoqiuleixing,
                            huiyuan_id=lx.huiyuan_id,
                            yongjin=lx.yongjin,
                            kaioi_ewai_dashou_fencheng=False,
                            ewai_dashou_fencheng=None,
                            paixu=100 - pi,
                            shenhezhuangtai=SHENHE,
                            shangjia_zhuangtai=True,
                            fengjin_zhuangtai=True,
                            shenhe_zhuangtai=True,
                            club_id=ALLOWED_CLUB_ID,
                            shi_zhuanpan=False,
                            dianpu=None,
                            dianpu_leixing=None,
                        )
                        stats['products_created'] += 1

            if stats['zones_created'] != 6 or stats['products_created'] != 60:
                raise CommandError(
                    f'数量异常: zones={stats["zones_created"]} products={stats["products_created"]}，'
                    f'期望 6/60，已回滚'
                )

        self.stdout.write(self.style.SUCCESS(
            f'\n完成: {stats}\n'
            f'均为审核专用(shenhezhuangtai=2)，仅审核模式可见；文案已避开代练代打。'
        ))
