"""
Management команда для отмены всех резервов в указанной схеме
Используется для очистки "зависших" резервов после ошибок
"""
from django.core.management.base import BaseCommand
from django.db import connection, transaction
from django.utils import timezone


class Command(BaseCommand):
    help = 'Отменяет все резервы (меняет статус на released) в указанной схеме'

    def add_arguments(self, parser):
        parser.add_argument(
            '--schema',
            type=str,
            required=True,
            help='Схема базы данных (tenant) для работы'
        )
        parser.add_argument(
            '--confirm',
            action='store_true',
            help='Подтверждение операции (без этого флага будет только показан список резервов)'
        )

    def handle(self, *args, **options):
        schema_name = options['schema']
        confirm = options.get('confirm', False)

        self.stdout.write('=' * 60)
        self.stdout.write(f'[INFO] Схема: {schema_name}')
        self.stdout.write('=' * 60)

        with connection.cursor() as cursor:
            # Устанавливаем схему
            cursor.execute(f'SET search_path TO {schema_name}')

            # Проверяем наличие резервов со статусом 'reserved'
            cursor.execute(f"""
                SELECT
                    r.id,
                    p.name as product_name,
                    r.quantity,
                    w.name as warehouse_name,
                    r.reserved_at,
                    r.order_item_id,
                    r.showcase_id,
                    r.product_kit_id
                FROM {schema_name}.inventory_reservation r
                JOIN {schema_name}.products_product p ON p.id = r.product_id
                JOIN {schema_name}.inventory_warehouse w ON w.id = r.warehouse_id
                WHERE r.status = 'reserved'
                ORDER BY r.reserved_at
            """)
            
            reservations = cursor.fetchall()
            
            if not reservations:
                self.stdout.write(self.style.SUCCESS('[OK] В схеме нет активных резервов со статусом "reserved"'))
                return

            self.stdout.write(f'\n[INFO] Найдено резервов со статусом "reserved": {len(reservations)}\n')

            # Группируем резервы по типу
            order_reservations = []
            showcase_reservations = []
            kit_reservations = []
            other_reservations = []

            for res in reservations:
                res_id, product_name, quantity, warehouse_name, reserved_at, order_item_id, showcase_id, product_kit_id = res
                
                if order_item_id:
                    order_reservations.append(res)
                elif showcase_id:
                    showcase_reservations.append(res)
                elif product_kit_id:
                    kit_reservations.append(res)
                else:
                    other_reservations.append(res)

            # Выводим статистику
            if order_reservations:
                self.stdout.write(f'  - Резервы для заказов: {len(order_reservations)}')
            if showcase_reservations:
                self.stdout.write(f'  - Резервы для витрин: {len(showcase_reservations)}')
            if kit_reservations:
                self.stdout.write(f'  - Резервы для комплектов: {len(kit_reservations)}')
            if other_reservations:
                self.stdout.write(f'  - Прочие резервы: {len(other_reservations)}')

            # Выводим детали первых 10 резервов
            self.stdout.write('\n[INFO] Первые 10 резервов:')
            for res in reservations[:10]:
                res_id, product_name, quantity, warehouse_name, reserved_at, order_item_id, showcase_id, product_kit_id = res
                
                context = []
                if order_item_id:
                    context.append(f'заказ #{order_item_id}')
                if showcase_id:
                    context.append(f'витрина #{showcase_id}')
                if product_kit_id:
                    context.append(f'комплект #{product_kit_id}')
                context_str = ', '.join(context) if context else 'без привязки'
                
                self.stdout.write(
                    f'  #{res_id}: {product_name} - {quantity} ед. на складе "{warehouse_name}" '
                    f'({reserved_at.strftime("%Y-%m-%d %H:%M:%S")}, {context_str})'
                )

            if not confirm:
                self.stdout.write('\n' + '=' * 60)
                self.stdout.write(self.style.WARNING('[ВНИМАНИЕ] Это режим предварительного просмотра'))
                self.stdout.write(self.style.WARNING(f'Для отмены всех {len(reservations)} резервов запустите команду с флагом --confirm:'))
                self.stdout.write(f'  python manage.py clear_reservations --schema={schema_name} --confirm')
                self.stdout.write('=' * 60)
                return

            # Подтверждение получено - отменяем все резервы
            self.stdout.write('\n' + '=' * 60)
            self.stdout.write(self.style.WARNING(f'[НАЧАЛО] Отмена {len(reservations)} резервов...'))
            self.stdout.write('=' * 60)

            with transaction.atomic():
                released_at = timezone.now()
                
                # Обновляем все резервы одним запросом
                cursor.execute(f"""
                    UPDATE {schema_name}.inventory_reservation
                    SET status = 'released',
                        released_at = %s
                    WHERE status = 'reserved'
                """, [released_at])
                
                updated_count = cursor.rowcount
                
                self.stdout.write(f'\n[OK] Обновлено резервов: {updated_count}')

                # Теперь пересчитываем quantity_reserved для всех затронутых Stock записей
                self.stdout.write('\n[INFO] Пересчет quantity_reserved для Stock записей...')
                
                # Получаем уникальные комбинации product_id + warehouse_id из освобожденных резервов
                cursor.execute(f"""
                    SELECT DISTINCT product_id, warehouse_id
                    FROM {schema_name}.inventory_reservation
                    WHERE released_at = %s
                """, [released_at])
                
                stock_updates = cursor.fetchall()
                
                for product_id, warehouse_id in stock_updates:
                    # Пересчитываем quantity_reserved для этой комбинации
                    cursor.execute(f"""
                        SELECT COALESCE(SUM(quantity), 0)
                        FROM {schema_name}.inventory_reservation
                        WHERE product_id = %s
                          AND warehouse_id = %s
                          AND status = 'reserved'
                    """, [product_id, warehouse_id])
                    
                    total_reserved = cursor.fetchone()[0]
                    
                    # Обновляем Stock
                    cursor.execute(f"""
                        UPDATE {schema_name}.inventory_stock
                        SET quantity_reserved = %s,
                            updated_at = CURRENT_TIMESTAMP
                        WHERE product_id = %s
                          AND warehouse_id = %s
                    """, [total_reserved, product_id, warehouse_id])

                self.stdout.write(f'[OK] Обновлено Stock записей: {len(stock_updates)}')

            self.stdout.write('\n' + '=' * 60)
            self.stdout.write(self.style.SUCCESS('[ЗАВЕРШЕНО] Все резервы успешно отменены!'))
            self.stdout.write(f'  Освобождено резервов: {updated_count}')
            self.stdout.write(f'  Обновлено Stock записей: {len(stock_updates)}')
            self.stdout.write('=' * 60)
