"""P1-10 默认数据 seed 命令

用法：
    python manage.py seed_affinity            # 写入默认数据，已存在则跳过
    python manage.py seed_affinity --force    # 强制覆盖已存在的默认规则/等级

写入内容（与「好感度系统功能与规则设计.md」§4.2 / §6.2 一致）：
    1. AffinitySetting 单例（如不存在）
    2. 8 条默认互动规则
    3. 5 个默认等级

幂等性：
    默认按 rule_key（规则）/ level（等级）查询，已存在则跳过。
    --force 模式下覆盖已存在记录的字段（不删旧记录）。
"""

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

from userapp.models import (
    AffinityRule,
    AffinityLevel,
    AffinitySetting,
)


# 默认规则，与设计文档 §4.2 一致
DEFAULT_RULES = [
    {
        'rule_key': 'card', 'name': '使用卡片', 'description': '用户使用洛天依卡片',
        'trigger_type': 'action',
        'min_change': 1, 'max_change': 3, 'single_cap': 3, 'daily_cap': 10,
        'cooldown_seconds': 0, 'is_negative': False, 'is_enabled': True,
    },
    {
        'rule_key': 'chat', 'name': '对话', 'description': '与洛天依进行对话',
        'trigger_type': 'action',
        'min_change': 1, 'max_change': 5, 'single_cap': 5, 'daily_cap': 15,
        'cooldown_seconds': 30, 'is_negative': False, 'is_enabled': True,
    },
    {
        'rule_key': 'feed', 'name': '喂食', 'description': '给洛天依喂食',
        'trigger_type': 'action',
        'min_change': 2, 'max_change': 8, 'single_cap': 8, 'daily_cap': 16,
        'cooldown_seconds': 0, 'is_negative': False, 'is_enabled': True,
    },
    {
        'rule_key': 'touch', 'name': '抚摸', 'description': '抚摸洛天依',
        'trigger_type': 'action',
        'min_change': 1, 'max_change': 3, 'single_cap': 3, 'daily_cap': 9,
        'cooldown_seconds': 10, 'is_negative': False, 'is_enabled': True,
    },
    {
        'rule_key': 'dress', 'name': '换装', 'description': '为洛天依更换服装',
        'trigger_type': 'action',
        'min_change': 2, 'max_change': 6, 'single_cap': 6, 'daily_cap': 12,
        'cooldown_seconds': 0, 'is_negative': False, 'is_enabled': True,
    },
    {
        'rule_key': 'prop', 'name': '使用道具', 'description': '使用互动道具',
        'trigger_type': 'action',
        'min_change': 1, 'max_change': 4, 'single_cap': 4, 'daily_cap': 12,
        'cooldown_seconds': 0, 'is_negative': False, 'is_enabled': True,
    },
    {
        'rule_key': 'gift', 'name': '送礼物', 'description': '赠送礼物给洛天依',
        'trigger_type': 'action',
        'min_change': 5, 'max_change': 15, 'single_cap': 15, 'daily_cap': 20,
        'cooldown_seconds': 0, 'is_negative': False, 'is_enabled': True,
    },
    {
        'rule_key': 'decay', 'name': '无互动衰减', 'description': '长时间不互动导致好感度下降',
        'trigger_type': 'decay',
        'min_change': -3, 'max_change': -1, 'single_cap': 3, 'daily_cap': 5,
        'cooldown_seconds': 0, 'is_negative': True, 'is_enabled': True,
    },
]


# 默认等级，与设计文档 §6.2 一致
DEFAULT_LEVELS = [
    {
        'level': 1, 'name': '初识', 'min_affinity': 0, 'max_affinity': 20,
        'unlock_content': '基础对话功能',
        'reward_type': 'unlock', 'reward_currency': 0, 'reward_items': [],
        'is_enabled': True,
    },
    {
        'level': 2, 'name': '相识', 'min_affinity': 21, 'max_affinity': 40,
        'unlock_content': '基础服装、道具使用',
        'reward_type': 'unlock', 'reward_currency': 0, 'reward_items': [],
        'is_enabled': True,
    },
    {
        'level': 3, 'name': '熟悉', 'min_affinity': 41, 'max_affinity': 60,
        'unlock_content': '更多服装、特殊对话',
        'reward_type': 'unlock', 'reward_currency': 0, 'reward_items': [],
        'is_enabled': True,
    },
    {
        'level': 4, 'name': '亲密', 'min_affinity': 61, 'max_affinity': 80,
        'unlock_content': '限定服装、特殊互动',
        'reward_type': 'unlock', 'reward_currency': 0, 'reward_items': [],
        'is_enabled': True,
    },
    {
        'level': 5, 'name': '挚友', 'min_affinity': 81, 'max_affinity': 100,
        'unlock_content': '专属内容、特殊剧情',
        'reward_type': 'unlock', 'reward_currency': 0, 'reward_items': [],
        'is_enabled': True,
    },
]


class Command(BaseCommand):
    help = '初始化好感度系统默认数据（AffinitySetting / AffinityRule / AffinityLevel）'

    def add_arguments(self, parser):
        parser.add_argument(
            '--force', action='store_true',
            help='强制覆盖已存在记录的字段（不删旧记录）',
        )

    @transaction.atomic
    def handle(self, *args, **options):
        force = options['force']

        self._seed_setting()
        rules_created, rules_updated = self._seed_rules(force)
        levels_created, levels_updated = self._seed_levels(force)

        self.stdout.write(self.style.SUCCESS(
            f'\n[seed_affinity] 完成：'
            f'规则 创建 {rules_created} 更新 {rules_updated}，'
            f'等级 创建 {levels_created} 更新 {levels_updated}'
        ))

    def _seed_setting(self):
        if AffinitySetting.objects.exists():
            self.stdout.write('AffinitySetting 已存在，跳过')
            return
        AffinitySetting.objects.create()
        self.stdout.write(self.style.SUCCESS('AffinitySetting 已创建（默认值）'))

    def _seed_rules(self, force):
        created = 0
        updated = 0
        for spec in DEFAULT_RULES:
            rule_key = spec['rule_key']
            existing = AffinityRule.objects.filter(rule_key=rule_key).first()
            if existing is None:
                AffinityRule.objects.create(**spec)
                created += 1
                self.stdout.write(f'  + 规则 {rule_key} 已创建')
            elif force:
                for k, v in spec.items():
                    setattr(existing, k, v)
                existing.save()
                updated += 1
                self.stdout.write(f'  ~ 规则 {rule_key} 已覆盖')
            else:
                self.stdout.write(f'  - 规则 {rule_key} 已存在，跳过')
        return created, updated

    def _seed_levels(self, force):
        created = 0
        updated = 0
        for spec in DEFAULT_LEVELS:
            level_num = spec['level']
            existing = AffinityLevel.objects.filter(level=level_num).first()
            if existing is None:
                AffinityLevel.objects.create(**spec)
                created += 1
                self.stdout.write(f'  + 等级 Lv{level_num} 已创建')
            elif force:
                for k, v in spec.items():
                    setattr(existing, k, v)
                existing.save()
                updated += 1
                self.stdout.write(f'  ~ 等级 Lv{level_num} 已覆盖')
            else:
                self.stdout.write(f'  - 等级 Lv{level_num} 已存在，跳过')
        return created, updated
