# -*- coding: utf-8 -*-
from django import forms
from django.forms import inlineformset_factory
from phonenumber_field.formfields import PhoneNumberField
from .models import Order, OrderItem, Transaction, Address, OrderStatus, Recipient, Delivery
from customers.models import Customer
from products.models import Product, ProductKit
from decimal import Decimal


class OrderForm(forms.ModelForm):
    """Форма для создания и редактирования заказа"""

    # Поля для работы с получателем
    other_recipient = forms.BooleanField(
        required=False,
        initial=False,
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}),
        label='Другой получатель',
        help_text='Если отмечено, получатель отличается от покупателя'
    )

    # Режим выбора другого получателя (история или новый)
    recipient_source = forms.ChoiceField(
        choices=[
            ('history', 'Выбрать из истории'),
            ('new', 'Новый получатель'),
        ],
        initial='new',
        widget=forms.RadioSelect(attrs={'class': 'form-check-input'}),
        required=False,
        label='Способ указания получателя'
    )

    # Выбор получателя из истории
    recipient_from_history = forms.ModelChoiceField(
        queryset=Recipient.objects.none(),
        required=False,
        widget=forms.Select(attrs={'class': 'form-select'}),
        label='Получатель из истории'
    )

    # Поля для нового получателя
    recipient_name = forms.CharField(
        max_length=200,
        required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Имя получателя'}),
        label='Имя получателя'
    )

    recipient_phone = PhoneNumberField(
        region=None,
        required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Телефон получателя'}),
        label='Телефон получателя',
        help_text='Введите телефон в любом формате, будет автоматически преобразован'
    )

    recipient_notes = forms.CharField(
        max_length=200,
        required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Мессенджер, соцсеть и т.д.'}),
        label='Дополнительная информация',
        help_text='Мессенджер, соцсеть или другая информация о получателе (необязательно)'
    )

    # Поля для работы с адресом
    address_mode = forms.ChoiceField(
        choices=[
            ('history', 'Выбрать из истории'),
            ('new', 'Ввести новый адрес'),
            ('empty', 'Без адреса (заполнить позже)'),
        ],
        initial='empty',
        widget=forms.RadioSelect(attrs={'class': 'form-check-input'}),
        required=False,
        label='Способ указания адреса'
    )

    # Выбор адреса из истории
    address_from_history = forms.ModelChoiceField(
        queryset=Address.objects.none(),
        required=False,
        widget=forms.Select(attrs={'class': 'form-select'}),
        label='Адрес из истории'
    )

    # Поля для ввода нового адреса
    address_street = forms.CharField(
        max_length=255,
        required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Улица'}),
        label='Улица'
    )

    address_building_number = forms.CharField(
        max_length=20,
        required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Номер дома'}),
        label='Номер дома'
    )

    address_apartment_number = forms.CharField(
        max_length=20,
        required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Квартира/офис'}),
        label='Квартира/офис'
    )

    address_entrance = forms.CharField(
        max_length=20,
        required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Подъезд'}),
        label='Подъезд'
    )

    address_floor = forms.CharField(
        max_length=20,
        required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Этаж'}),
        label='Этаж'
    )

    address_intercom_code = forms.CharField(
        max_length=100,
        required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Код домофона'}),
        label='Код домофона'
    )

    address_delivery_instructions = forms.CharField(
        required=False,
        widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3, 'placeholder': 'Инструкции для курьера'}),
        label='Инструкции для доставки'
    )

    address_confirm_with_recipient = forms.BooleanField(
        required=False,
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}),
        label='Уточнить адрес у получателя'
    )

    # Поля для доставки
    delivery_type = forms.ChoiceField(
        choices=Delivery.DELIVERY_TYPE_CHOICES,
        required=True,
        widget=forms.RadioSelect(attrs={'class': 'form-check-input'}),
        label='Способ доставки',
        initial=Delivery.DELIVERY_TYPE_COURIER
    )

    delivery_date = forms.DateField(
        required=True,
        widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
        label='Дата доставки'
    )

    time_from = forms.TimeField(
        required=False,
        widget=forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'}),
        label='Время доставки от'
    )

    time_to = forms.TimeField(
        required=False,
        widget=forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'}),
        label='Время доставки до'
    )

    pickup_warehouse = forms.ModelChoiceField(
        queryset=None,  # Будет установлен в __init__
        required=False,
        widget=forms.Select(attrs={'class': 'form-select'}),
        label='Склад самовывоза',
        empty_label='Выберите склад'
    )

    delivery_cost = forms.DecimalField(
        required=False,
        max_digits=10,
        decimal_places=2,
        widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01', 'min': '0'}),
        label='Стоимость доставки',
        initial=0
    )

    class Meta:
        model = Order
        fields = [
            'customer',
            'recipient',
            'status',
            'is_anonymous',
            'needs_product_photo',
            'needs_delivery_photo',
            'special_instructions',
            'summary',
        ]
        widgets = {
            'special_instructions': forms.Textarea(attrs={'rows': 3}),
            'summary': forms.Textarea(attrs={
                'rows': 5,
                'placeholder': 'Кратко опишите заказ на естественном языке...',
                'class': 'form-control',
                'style': 'resize: vertical; min-height: 100px;'
            }),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Ограничиваем выбор статусов при создании заказа только промежуточными
        # (исключаем финальные положительные и отрицательные статусы)
        if not self.instance.pk:
            from .models import OrderStatus
            # Только промежуточные статусы (не финальные)
            intermediate_statuses = OrderStatus.objects.filter(
                is_positive_end=False,
                is_negative_end=False
            ).order_by('order', 'name')
            self.fields['status'].queryset = intermediate_statuses
            
            # Устанавливаем статус "Черновик" по умолчанию
            try:
                draft_status = OrderStatus.objects.get(code='draft', is_system=True)
                self.fields['status'].initial = draft_status.pk
            except OrderStatus.DoesNotExist:
                pass
        else:
            # При редактировании заказа доступны все статусы
            from .models import OrderStatus
            self.fields['status'].queryset = OrderStatus.objects.all().order_by('order', 'name')

        # Делаем поле status обязательным и убираем пустой выбор "-------"
        self.fields['status'].required = True
        self.fields['status'].empty_label = None

        # Добавляем Bootstrap классы ко всем полям
        for field_name, field in self.fields.items():
            if isinstance(field.widget, forms.CheckboxInput):
                field.widget.attrs.update({'class': 'form-check-input'})
            elif isinstance(field.widget, forms.Textarea):
                field.widget.attrs.update({'class': 'form-control', 'rows': 3})
            elif isinstance(field.widget, forms.RadioSelect):
                # RadioSelect не нуждается в доп классах (уже есть form-check-input)
                pass
            elif isinstance(field.widget, forms.Select):
                # Select поля получают form-select
                field.widget.attrs.update({'class': 'form-select'})
            else:
                # Остальные поля (TextInput, NumberInput, etc)
                field.widget.attrs.update({'class': 'form-control'})

        # Select2 для поля customer с AJAX поиском (инициализируется отдельно в JS)
        # Django автоматически генерирует ID как id_customer
        self.fields['customer'].widget.attrs.update({
            'class': 'form-select',
            'data-placeholder': 'Начните вводить имя, телефон или email'
        })

        # Поле получателя опционально
        self.fields['recipient'].required = False

        # Инициализируем чекбокс other_recipient на основе наличия recipient
        if self.instance.pk:
            # При редактировании заказа: если есть recipient, чекбокс включен
            if self.instance.recipient:
                self.fields['other_recipient'].initial = True
                # Определяем источник получателя
                # Проверяем, есть ли этот recipient в истории клиента
                if self.instance.customer:
                    customer_orders = Order.objects.filter(
                        customer=self.instance.customer,
                        recipient__isnull=False
                    ).exclude(pk=self.instance.pk).order_by('-created_at')
                    history_recipients = Recipient.objects.filter(
                        orders__in=customer_orders
                    ).distinct()
                    if self.instance.recipient in history_recipients:
                        self.fields['recipient_source'].initial = 'history'
                        self.fields['recipient_from_history'].initial = self.instance.recipient.pk
                    else:
                        self.fields['recipient_source'].initial = 'new'
                        self.fields['recipient_name'].initial = self.instance.recipient.name or ''
                        self.fields['recipient_phone'].initial = str(self.instance.recipient.phone) if self.instance.recipient.phone else ''
                        self.fields['recipient_notes'].initial = self.instance.recipient.notes or ''
            else:
                self.fields['other_recipient'].initial = False

        # Инициализируем queryset для recipient_from_history
        if self.instance.pk and self.instance.customer:
            # При редактировании заказа загружаем историю получателей этого клиента
            customer_orders = Order.objects.filter(
                customer=self.instance.customer,
                recipient__isnull=False
            ).exclude(pk=self.instance.pk).order_by('-created_at')
            self.fields['recipient_from_history'].queryset = Recipient.objects.filter(
                orders__in=customer_orders
            ).distinct().order_by('-created_at')
        elif not self.instance.pk:
            # При создании нового заказа queryset пустой (будет заполнен через JS при выборе клиента)
            self.fields['recipient_from_history'].queryset = Recipient.objects.none()

        # Инициализируем queryset для pickup_warehouse
        # Фильтруем только активные склады, доступные для самовывоза
        # Сортируем: сначала склад по умолчанию, потом по названию
        from inventory.models import Warehouse
        self.fields['pickup_warehouse'].queryset = Warehouse.objects.filter(
            is_active=True,
            is_pickup_point=True
        ).order_by('-is_default', 'name')
        
        # Если это новый заказ и еще не выбран склад, выбираем склад по умолчанию
        if not self.instance.pk:
            default_warehouse = Warehouse.objects.filter(
                is_active=True,
                is_pickup_point=True,
                is_default=True
            ).first()
            if default_warehouse:
                self.fields['pickup_warehouse'].initial = default_warehouse

        # Инициализируем поля доставки из существующей Delivery
        if self.instance.pk and hasattr(self.instance, 'delivery'):
            delivery = self.instance.delivery
            
            # Устанавливаем значения через fields.initial для правильной работы виджетов
            self.fields['delivery_type'].initial = delivery.delivery_type
            self.fields['delivery_date'].initial = delivery.delivery_date
            self.fields['time_from'].initial = delivery.time_from
            self.fields['time_to'].initial = delivery.time_to
            self.fields['pickup_warehouse'].initial = delivery.pickup_warehouse
            self.fields['delivery_cost'].initial = delivery.cost
            
            # Также устанавливаем через self.initial для совместимости
            self.initial['delivery_type'] = delivery.delivery_type
            self.initial['delivery_date'] = delivery.delivery_date
            self.initial['time_from'] = delivery.time_from
            self.initial['time_to'] = delivery.time_to
            self.initial['pickup_warehouse'] = delivery.pickup_warehouse
            self.initial['delivery_cost'] = delivery.cost
            
            # Для DateInput с type='date' нужно установить значение в формате YYYY-MM-DD
            if delivery.delivery_date:
                # Устанавливаем значение напрямую в виджете
                self.fields['delivery_date'].widget.attrs['value'] = delivery.delivery_date.strftime('%Y-%m-%d')
            
            # Если выбран самовывоз, но склад не указан - выбираем склад по умолчанию
            if delivery.delivery_type == Delivery.DELIVERY_TYPE_PICKUP and not delivery.pickup_warehouse:
                default_warehouse = Warehouse.objects.filter(
                    is_active=True,
                    is_pickup_point=True,
                    is_default=True
                ).first()
                if default_warehouse:
                    self.fields['pickup_warehouse'].initial = default_warehouse
            
            # Инициализируем поля адреса, если есть адрес доставки
            if delivery.address:
                # При редактировании всегда используем режим "новый", чтобы можно было редактировать адрес
                # Инициализируем queryset для истории адресов (для выбора из истории, если нужно)
                if self.instance.customer:
                    customer_addresses = Address.objects.filter(
                        deliveries__order__customer=self.instance.customer
                    ).exclude(
                        deliveries__order=self.instance  # Исключаем адрес текущего заказа
                    ).distinct()
                    self.fields['address_from_history'].queryset = customer_addresses
                
                # Всегда используем режим "новый" для редактирования, чтобы можно было редактировать
                self.initial['address_mode'] = 'new'
                self.initial['address_street'] = delivery.address.street
                self.initial['address_building_number'] = delivery.address.building_number
                self.initial['address_apartment_number'] = delivery.address.apartment_number
                self.initial['address_entrance'] = delivery.address.entrance
                self.initial['address_floor'] = delivery.address.floor
                self.initial['address_intercom_code'] = delivery.address.intercom_code
                self.initial['address_delivery_instructions'] = delivery.address.delivery_instructions
                self.initial['address_confirm_with_recipient'] = delivery.address.confirm_address_with_recipient

    def clean(self):
        """Валидация формы заказа, включая обязательные поля доставки"""
        cleaned_data = super().clean()
        
        # Проверяем, является ли заказ черновиком
        status = cleaned_data.get('status')
        is_draft = status and hasattr(status, 'code') and status.code == 'draft'
        
        # Для черновиков Delivery не обязательна
        if is_draft:
            return cleaned_data
        
        # Для не-черновиков Delivery обязательна
        delivery_type = cleaned_data.get('delivery_type')
        delivery_date = cleaned_data.get('delivery_date')
        time_from = cleaned_data.get('time_from')
        time_to = cleaned_data.get('time_to')
        pickup_warehouse = cleaned_data.get('pickup_warehouse')
        
        # Проверяем обязательные поля доставки
        if not delivery_type:
            raise forms.ValidationError({'delivery_type': 'Необходимо выбрать способ доставки'})
        
        if not delivery_date:
            raise forms.ValidationError({'delivery_date': 'Необходимо указать дату доставки'})
        
        # Время необязательно, но если указано одно, должно быть указано и другое
        if (time_from and not time_to) or (time_to and not time_from):
            raise forms.ValidationError({
                'time_to': 'Если указано время начала, необходимо указать и время окончания, и наоборот'
            })
        
        # Проверяем, что время "до" позже времени "от" (если оба указаны)
        if time_from and time_to and time_from >= time_to:
            raise forms.ValidationError({
                'time_to': 'Время окончания доставки должно быть позже времени начала'
            })
        
        # Проверяем специфичные требования для каждого типа доставки
        if delivery_type == Delivery.DELIVERY_TYPE_COURIER:
            # Для курьерской доставки нужен адрес
            address_mode = cleaned_data.get('address_mode')
            address_from_history = cleaned_data.get('address_from_history')
            address_street = cleaned_data.get('address_street', '').strip()
            
            has_address = (
                (address_mode == 'history' and address_from_history) or
                (address_mode == 'new' and address_street) or
                address_mode == 'empty'  # Разрешаем "Без адреса (заполнить позже)"
            )
            
            if not has_address:
                raise forms.ValidationError({
                    'address_mode': 'Для курьерской доставки необходимо указать адрес'
                })
        
        elif delivery_type == Delivery.DELIVERY_TYPE_PICKUP:
            # Для самовывоза нужен склад
            if not pickup_warehouse:
                raise forms.ValidationError({
                    'pickup_warehouse': 'Для самовывоза необходимо выбрать склад'
                })
        
        return cleaned_data

    def save(self, commit=True):
        """Сохраняет форму заказа."""
        instance = super().save(commit=False)

        if commit:
            instance.save()

        return instance


class OrderItemForm(forms.ModelForm):
    """Форма для позиции заказа"""

    # Элегантно переопределяем поле формы, чтобы парсить '277,00' как Decimal
    price = forms.CharField(
        required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'step': '0.01', 'min': '0'})
    )

    # Поле DELETE, которое автоматически добавляется в inline формсете
    DELETE = forms.BooleanField(required=False, widget=forms.HiddenInput())

    class Meta:
        model = OrderItem
        fields = ['id', 'product', 'product_kit', 'sales_unit', 'quantity', 'price', 'is_custom_price', 'is_from_showcase']
        # ВАЖНО: Теперь включаем 'id' в fields для правильной работы inline формсета
        widgets = {
            'id': forms.HiddenInput(),  # Скрываем поле id, но оставляем его для формсета
            'quantity': forms.NumberInput(attrs={'min': 1}),
            # Скрываем поля product и product_kit - они будут заполняться через JS
            'product': forms.HiddenInput(),
            'product_kit': forms.HiddenInput(),
            'sales_unit': forms.HiddenInput(),  # Управляется через JS
            'is_custom_price': forms.HiddenInput(),
            'is_from_showcase': forms.HiddenInput(),  # Устанавливается через JS для showcase_kit
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Bootstrap классы
        for field_name, field in self.fields.items():
            if not isinstance(field.widget, forms.HiddenInput):
                css_class = 'form-control'
                # Добавляем is-invalid если есть ошибки в поле
                if self.errors.get(field_name):
                    css_class += ' is-invalid'
                field.widget.attrs.update({'class': css_class})

        # Поля product и product_kit опциональны
        self.fields['product'].required = False
        self.fields['product_kit'].required = False

        # Поле sales_unit опционально (управляется через JS)
        self.fields['sales_unit'].required = False

        # Поле цены заполняется автоматически, но можно редактировать вручную
        self.fields['price'].widget.attrs.update({
            'placeholder': 'Цена',
            'step': '0.01'
        })
        self.fields['price'].required = False

        # Поле is_custom_price устанавливается через JS
        self.fields['is_custom_price'].required = False
        
        # Поле is_from_showcase устанавливается через JS для showcase_kit
        self.fields['is_from_showcase'].required = False

    def clean_price(self):
        """Парсим цену с запятой или точкой и округляем до 2 знаков"""
        value = self.cleaned_data.get('price')
        if value in (None, ''):
            return None
        value_str = str(value).strip().replace(',', '.')
        try:
            price = Decimal(value_str)
            # Округляем до 2 знаков после запятой
            return price.quantize(Decimal('0.01'))
        except Exception:
            raise forms.ValidationError('Введите число.')

    def clean(self):
        """Валидация: должен быть выбран либо товар, либо комплект (не оба, не ни один)"""
        cleaned_data = super().clean()
        product = cleaned_data.get('product')
        product_kit = cleaned_data.get('product_kit')
        sales_unit = cleaned_data.get('sales_unit')
        quantity = cleaned_data.get('quantity')

        # Пустая форма - это нормально (будет удалена)
        if not product and not product_kit:
            # Обнуляем количество для пустых форм
            cleaned_data['quantity'] = None
            return cleaned_data

        # Проверка: нельзя выбрать оба одновременно
        if product and product_kit:
            raise forms.ValidationError(
                'Нельзя указывать одновременно товар и комплект. Выберите что-то одно.'
            )

        # Проверка: если выбрано что-то, количество обязательно
        if (product or product_kit):
            if not quantity or quantity <= 0:
                raise forms.ValidationError('Необходимо указать количество больше 0')

        # Валидация единицы продажи
        if sales_unit:
            if product and sales_unit.product_id != product.id:
                raise forms.ValidationError('Единица продажи не принадлежит товару')

            if quantity:
                try:
                    sales_unit.validate_quantity(quantity)
                except ValidationError as e:
                    raise forms.ValidationError(str(e))

        return cleaned_data


# Formset для inline добавления товаров в заказ
OrderItemFormSet = inlineformset_factory(
    Order,
    OrderItem,
    form=OrderItemForm,
    extra=0,  # Без пустых форм (будем добавлять через JavaScript)
    can_delete=True,
    min_num=0,  # Минимум 0 товаров (валидация на уровне бизнес-логики)
    validate_min=False,
)


# === СТАТУСЫ ЗАКАЗОВ ===

class OrderStatusForm(forms.ModelForm):
    """Форма для создания и редактирования статусов заказов"""

    class Meta:
        model = OrderStatus
        fields = [
            'name',
            'code',
            'label',
            'color',
            'description',
            'is_positive_end',
            'is_negative_end',
        ]
        widgets = {
            'name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Например: Выполнен, В процессе'
            }),
            'code': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Например: completed, in_progress'
            }),
            'label': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Метка для отображения (опционально)'
            }),
            'color': forms.TextInput(attrs={
                'class': 'form-control',
                'type': 'color'
            }),
            'description': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 3,
                'placeholder': 'Описание статуса (опционально)'
            }),
            'is_positive_end': forms.CheckboxInput(attrs={
                'class': 'form-check-input'
            }),
            'is_negative_end': forms.CheckboxInput(attrs={
                'class': 'form-check-input'
            }),
        }

    def clean(self):
        cleaned_data = super().clean()

        # Нельзя быть одновременно положительным и отрицательным концом
        if cleaned_data.get('is_positive_end') and cleaned_data.get('is_negative_end'):
            raise forms.ValidationError(
                "Статус не может быть одновременно положительным и отрицательным концом"
            )

        # Системные статусы нельзя редактировать код
        if self.instance.pk and self.instance.is_system:
            original_code = OrderStatus.objects.get(pk=self.instance.pk).code
            new_code = cleaned_data.get('code')
            if original_code != new_code:
                raise forms.ValidationError(
                    "Нельзя менять код системного статуса"
                )

        return cleaned_data

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Если редактируем системный статус - делаем код readonly
        if self.instance.pk and self.instance.is_system:
            self.fields['code'].widget.attrs['readonly'] = True
            self.fields['code'].help_text = "Код системного статуса нельзя менять"

            # КРИТИЧНО: Блокируем изменение флагов is_positive_end и is_negative_end
            # Эти флаги используются в сигналах для управления резервами и списаниями
            # Изменение может привести к:
            # - Неправильному освобождению резервов
            # - Двойному резервированию товара
            # - Блокировке товара навсегда
            self.fields['is_positive_end'].disabled = True
            self.fields['is_negative_end'].disabled = True
            self.fields['is_positive_end'].help_text = "Нельзя изменять для системных статусов (влияет на резервирование)"
            self.fields['is_negative_end'].help_text = "Нельзя изменять для системных статусов (влияет на резервирование)"


# === ВРЕМЕННЫЕ КОМПЛЕКТЫ ===

class TemporaryKitForm(forms.ModelForm):
    """
    Упрощенная форма для создания временного комплекта.
    Используется при оформлении заказа для создания букета "на лету".
    """

    class Meta:
        model = ProductKit
        fields = ['name', 'description']
        widgets = {
            'description': forms.Textarea(attrs={'rows': 2, 'placeholder': 'Краткое описание (опционально)'}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Bootstrap классы
        for field in self.fields.values():
            if isinstance(field.widget, forms.Textarea):
                field.widget.attrs.update({'class': 'form-control'})
            else:
                field.widget.attrs.update({'class': 'form-control'})

        # Название обязательно
        self.fields['name'].required = True
        self.fields['name'].widget.attrs.update({
            'placeholder': 'Название временного букета (например: "Букет для Анны")'
        })

        # Описание опционально
        self.fields['description'].required = False


class TemporaryKitItemForm(forms.Form):
    """
    Форма для компонента временного комплекта.
    Используется в формсете для добавления товаров в букет.
    """
    product = forms.IntegerField(required=False, widget=forms.HiddenInput())
    quantity = forms.DecimalField(
        required=False,
        min_value=0.001,
        max_digits=10,
        decimal_places=3,
        widget=forms.NumberInput(attrs={'class': 'form-control', 'min': '0.001', 'step': '1'})
    )

    def clean(self):
        cleaned_data = super().clean()
        product_id = cleaned_data.get('product')
        quantity = cleaned_data.get('quantity')

        # Пустая форма - это нормально (будет удалена)
        if not product_id:
            return cleaned_data

        # Если выбран товар, количество обязательно
        if product_id and (not quantity or quantity <= 0):
            raise forms.ValidationError('Необходимо указать количество больше 0')

        return cleaned_data


# Formset для компонентов временного комплекта
from django.forms import formset_factory

TemporaryKitItemFormSet = formset_factory(
    TemporaryKitItemForm,
    extra=1,  # Одна пустая форма для добавления
    can_delete=True,
    min_num=1,  # Минимум 1 компонент в комплекте
    validate_min=True,
)


# === ТРАНЗАКЦИИ (СМЕШАННАЯ ОПЛАТА И ВОЗВРАТЫ) ===

class TransactionForm(forms.ModelForm):
    """
    Форма для создания транзакций по заказу.
    Поддерживает смешанную оплату и возвраты.
    """
    class Meta:
        model = Transaction
        fields = ['payment_method', 'amount', 'notes']
        widgets = {
            'payment_method': forms.Select(attrs={'class': 'form-select'}),
            'amount': forms.NumberInput(attrs={
                'class': 'form-control',
                'step': '0.01',
                'min': '0',
                'placeholder': 'Сумма платежа'
            }),
            'notes': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 2,
                'placeholder': 'Примечания к платежу (опционально)'
            }),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Фильтруем только активные способы оплаты
        from .models import PaymentMethod
        self.fields['payment_method'].queryset = PaymentMethod.objects.filter(
            is_active=True
        ).order_by('order', 'name')

        # Делаем notes опциональным
        self.fields['notes'].required = False

    def clean(self):
        """Валидация платежа, особенно для оплаты из кошелька"""
        cleaned = super().clean()
        method = cleaned.get('payment_method')
        amount = cleaned.get('amount')
        order = getattr(self.instance, 'order', None)

        # Пустые формы допустимы при удалении
        if not method and not amount:
            return cleaned

        # Базовые проверки
        if amount is None or amount <= 0:
            self.add_error('amount', 'Введите сумму больше 0.')

        # ВАЖНО: order может быть None при создании нового заказа!
        # Проверки кошелька делаем только если order уже существует
        if order and method and getattr(method, 'code', None) == 'account_balance':
            wallet_balance = order.customer.wallet_balance if order.customer else Decimal('0')
            amount_due = max(order.total_amount - order.amount_paid, Decimal('0'))

            if wallet_balance <= 0:
                self.add_error('payment_method', 'Недостаточно средств в кошельке клиента (баланс 0).')

            if amount and amount > wallet_balance:
                self.add_error('amount', f'Недостаточно средств в кошельке. Доступно {wallet_balance} руб.')

            if amount and amount > amount_due:
                self.add_error('amount', f'Сумма превышает остаток к оплате ({amount_due} руб.)')

            if self.errors:
                # Общее сообщение для блока формы
                raise forms.ValidationError('Проверьте поля оплаты из кошелька.')

        return cleaned


# Formset для множественных транзакций
TransactionFormSet = inlineformset_factory(
    Order,
    Transaction,
    form=TransactionForm,
    extra=0,  # Без пустых форм (добавляем через JavaScript)
    can_delete=False,  # Используйте refund вместо удаления
    min_num=0,  # Транзакции не обязательны при создании черновика
    validate_min=False,
)
