"""修复 config.0006 半路失败：去重 + 补唯一约束/索引，然后 fake 0006。"""
from django.core.management.base import BaseCommand
from django.db import connection
from django.db.models import Max

from config.models import PopupPage, Tupianpeizhi


def _table_indexes(table):
    with connection.cursor() as cursor:
        cursor.execute(f'SHOW INDEX FROM `{table}`')
        rows = cursor.fetchall()
    # Key_name, Column_name, Non_unique
    by_key = {}
    for row in rows:
        key_name = row[2]
        col = row[4]
        non_unique = row[1]
        by_key.setdefault(key_name, {'cols': [], 'unique': non_unique == 0})
        by_key[key_name]['cols'].append(col)
    return by_key


def _has_unique_on(table, columns):
    cols = list(columns)
    for info in _table_indexes(table).values():
        if info['unique'] and info['cols'] == cols:
            return True
    return False


def _drop_index(table, key_name):
    with connection.cursor() as cursor:
        cursor.execute(f'ALTER TABLE `{table}` DROP INDEX `{key_name}`')


def _add_unique(table, name, columns):
    cols = ', '.join(f'`{c}`' for c in columns)
    with connection.cursor() as cursor:
        cursor.execute(f'ALTER TABLE `{table}` ADD UNIQUE `{name}` ({cols})')


def _add_index(table, name, columns):
    cols = ', '.join(f'`{c}`' for c in columns)
    with connection.cursor() as cursor:
        cursor.execute(f'CREATE INDEX `{name}` ON `{table}` ({cols})')


class Command(BaseCommand):
    help = 'config.0006 半路失败时：清重复数据、补约束，再执行 migrate config 0006 --fake'

    def handle(self, *args, **options):
        self.stdout.write('1) 清理重复数据…')

        for row in Tupianpeizhi.objects.values('club_id', 'ImageType').annotate(max_id=Max('id')):
            n = Tupianpeizhi.objects.filter(
                club_id=row['club_id'],
                ImageType=row['ImageType'],
            ).exclude(id=row['max_id']).delete()[0]
            if n:
                self.stdout.write(f'  tupianpeizhi 删除 {n} 条重复')

        for row in PopupPage.objects.values('club_id', 'page_key').annotate(max_id=Max('id')):
            n = PopupPage.objects.filter(
                club_id=row['club_id'],
                page_key=row['page_key'],
            ).exclude(id=row['max_id']).delete()[0]
            if n:
                self.stdout.write(f'  popup_page 删除 {n} 条重复')

        self.stdout.write('2) 检查并补约束/索引…')

        # popup_page：去掉 page_key 单独唯一，改为 (club_id, page_key)
        popup_indexes = _table_indexes('popup_page')
        for key_name, info in popup_indexes.items():
            if info['unique'] and info['cols'] == ['page_key']:
                self.stdout.write(f'  删除 popup_page 旧唯一索引 {key_name}')
                _drop_index('popup_page', key_name)

        if not _has_unique_on('popup_page', ['club_id', 'page_key']):
            self.stdout.write('  添加 popup_page UNIQUE (club_id, page_key)')
            _add_unique('popup_page', 'popup_page_club_page_key_uniq', ['club_id', 'page_key'])
        else:
            self.stdout.write('  popup_page UNIQUE (club_id, page_key) 已存在')

        if not _has_unique_on('tupianpeizhi', ['club_id', 'ImageType']):
            self.stdout.write('  添加 tupianpeizhi UNIQUE (club_id, ImageType)')
            _add_unique('tupianpeizhi', 'tupianpeizhi_club_id_ImageType_uniq', ['club_id', 'ImageType'])
        else:
            self.stdout.write('  tupianpeizhi UNIQUE (club_id, ImageType) 已存在')

        lunbo_indexes = _table_indexes('lunbo')
        if 'lunbo_club_page_type_idx' not in lunbo_indexes:
            self.stdout.write('  添加 lunbo 索引 lunbo_club_page_type_idx')
            _add_index('lunbo', 'lunbo_club_page_type_idx', ['club_id', 'page_key', 'ImageType'])
        else:
            self.stdout.write('  lunbo 索引 lunbo_club_page_type_idx 已存在')

        self.stdout.write(self.style.SUCCESS(
            '\n完成。请执行：\n'
            '  python manage.py migrate config 0006 --fake\n'
            '  python manage.py migrate config\n'
            '  python manage.py migrate\n'
        ))
