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

from orders.models import OrderItem
from inventory.models import Reservation, Warehouse


class Command(BaseCommand):
    help = 'Создает недостающие резервы для существующих заказов'

    def add_arguments(self, parser):
        parser.add_argument(
            '--schema',
            type=str,
            default='grach',
            help='Схема базы данных (tenant) для работы'
        )
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='Показать что будет сделано, но не применять изменения'
        )

    def handle(self, *args, **options):
        schema_name = options['schema']
        dry_run = options['dry_run']

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

        self.stdout.write(f'[НАЧАЛО] Поиск заказов без резервов в схеме {schema_name}...')

        if dry_run:
            self.stdout.write(self.style.WARNING('[DRY RUN] Режим просмотра - изменения НЕ будут применены'))

        # Получаем активный склад (если есть)
        try:
            warehouse = Warehouse.objects.filter(is_active=True).first()
            if warehouse:
                self.stdout.write(f'[INFO] Используем склад: {warehouse.name}')
            else:
                self.stdout.write(self.style.WARNING('[ВНИМАНИЕ] Нет активного склада, резервы будут созданы без привязки к складу'))
        except Exception as e:
            self.stdout.write(self.style.WARNING(f'[ВНИМАНИЕ] Не удалось получить склад: {e}'))
            warehouse = None

        # Находим все OrderItem без резервов
        items_without_reservations = OrderItem.objects.filter(
            reservations__isnull=True
        ).select_related('order', 'product', 'product_kit')

        total_items = items_without_reservations.count()

        if total_items == 0:
            self.stdout.write(self.style.SUCCESS('[OK] Все заказы имеют резервы!'))
            return

        self.stdout.write(f'[НАЙДЕНО] {total_items} позиций заказов без резервов')

        created_count = 0
        errors_count = 0

        with transaction.atomic():
            for item in items_without_reservations:
                try:
                    # Определяем товар (может быть product или product_kit)
                    product = item.product if item.product else item.product_kit

                    if not product:
                        self.stdout.write(
                            self.style.WARNING(
                                f'[ПРОПУСК] OrderItem #{item.id}: нет товара'
                            )
                        )
                        errors_count += 1
                        continue

                    # Создаем резерв
                    if not dry_run:
                        reservation = Reservation.objects.create(
                            order_item=item,
                            product=product,
                            warehouse=warehouse,
                            quantity=item.quantity,
                            status='reserved'
                        )

                        self.stdout.write(
                            f'  [OK] Резерв #{reservation.id}: '
                            f'Заказ {item.order.order_number}, '
                            f'Товар "{product.name}", '
                            f'Кол-во: {item.quantity}'
                        )
                    else:
                        self.stdout.write(
                            f'  [DRY RUN] Будет создан резерв: '
                            f'Заказ {item.order.order_number}, '
                            f'Товар "{product.name}", '
                            f'Кол-во: {item.quantity}'
                        )

                    created_count += 1

                except Exception as e:
                    self.stdout.write(
                        self.style.ERROR(
                            f'[ОШИБКА] OrderItem #{item.id}: {str(e)}'
                        )
                    )
                    errors_count += 1

            if dry_run:
                # В режиме dry-run откатываем транзакцию
                transaction.set_rollback(True)
                self.stdout.write(
                    self.style.WARNING(
                        f'\n[DRY RUN] Изменения НЕ применены (транзакция откачена)'
                    )
                )

        # Итоги
        self.stdout.write('\n' + '=' * 60)
        if dry_run:
            self.stdout.write(self.style.WARNING('[DRY RUN] Результаты (БЕЗ изменений):'))
            self.stdout.write(f'  Будет создано резервов: {created_count}')
            self.stdout.write(f'  Ошибок/пропусков: {errors_count}')
            self.stdout.write('\nДля применения изменений запустите без флага --dry-run')
        else:
            self.stdout.write(self.style.SUCCESS('[ЗАВЕРШЕНО] Результаты:'))
            self.stdout.write(f'  Создано резервов: {created_count}')
            self.stdout.write(f'  Ошибок/пропусков: {errors_count}')
            self.stdout.write(self.style.SUCCESS('\n✓ Резервы успешно восстановлены!'))
