# -*- coding: utf-8 -*-
from django import forms
from django.core.exceptions import ValidationError
from decimal import Decimal

from .models import (
    Warehouse, Sale, WriteOff, Reservation, Inventory, InventoryLine, StockBatch,
    TransferDocument, TransferDocumentItem, Showcase, WriteOffDocument, WriteOffDocumentItem, Stock,
    IncomingDocument, IncomingDocumentItem, Transformation, TransformationInput, TransformationOutput
)
from products.models import Product


class WarehouseForm(forms.ModelForm):
    class Meta:
        model = Warehouse
        fields = [
            'name',
            'description',
            'street',
            'building_number',
            'phone',
            'email',
            'is_active',
            'is_default',
            'is_pickup_point'
        ]
        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Название склада'}),
            'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3, 'placeholder': 'Описание'}),
            'street': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Улица'}),
            'building_number': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Номер дома'}),
            'phone': forms.TextInput(attrs={'class': 'form-control', 'placeholder': '+375 (29) 123-45-67'}),
            'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'email@example.com'}),
            'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'is_default': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'is_pickup_point': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
        }
        help_texts = {
            'is_default': 'Автоматически выбирается при создании новых документов',
            'is_pickup_point': 'Можно ли выбрать этот склад как точку самовывоза заказа',
        }


class SaleForm(forms.ModelForm):
    class Meta:
        model = Sale
        fields = ['product', 'warehouse', 'sales_unit', 'quantity', 'sale_price', 'order', 'document_number']
        widgets = {
            'product': forms.Select(attrs={'class': 'form-control'}),
            'warehouse': forms.Select(attrs={'class': 'form-control'}),
            'sales_unit': forms.Select(attrs={'class': 'form-control'}),
            'quantity': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.001'}),
            'sale_price': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}),
            'order': forms.Select(attrs={'class': 'form-control'}),
            'document_number': forms.TextInput(attrs={'class': 'form-control'}),
        }

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

        # Динамический queryset для sales_unit
        if self.instance.pk and self.instance.product:
            from products.models import ProductSalesUnit
            self.fields['sales_unit'].queryset = ProductSalesUnit.objects.filter(
                product=self.instance.product,
                is_active=True
            ).order_by('position', 'id')
        else:
            from products.models import ProductSalesUnit
            self.fields['sales_unit'].queryset = ProductSalesUnit.objects.none()

        self.fields['sales_unit'].required = False

    def clean_quantity(self):
        quantity = self.cleaned_data.get('quantity')
        if quantity and quantity <= 0:
            raise ValidationError('Количество должно быть больше нуля')
        return quantity

    def clean_sale_price(self):
        sale_price = self.cleaned_data.get('sale_price')
        if sale_price and sale_price < 0:
            raise ValidationError('Цена не может быть отрицательной')
        return sale_price


# WriteOffForm удалён - используйте WriteOffDocumentForm для работы с документами списания


class InventoryForm(forms.ModelForm):
    class Meta:
        model = Inventory
        fields = ['warehouse', 'notes']
        widgets = {
            'warehouse': forms.Select(attrs={'class': 'form-control'}),
            'notes': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        # Фильтруем только активные склады (исключаем скрытые)
        self.fields['warehouse'].queryset = Warehouse.objects.filter(is_active=True)
        
        # Если есть склад по умолчанию и значение не установлено явно - предвыбираем его
        if not self.initial.get('warehouse'):
            default_warehouse = Warehouse.objects.filter(
                is_active=True,
                is_default=True
            ).first()
            if default_warehouse:
                self.initial['warehouse'] = default_warehouse.id


class InventoryLineForm(forms.ModelForm):
    class Meta:
        model = InventoryLine
        fields = ['product', 'quantity_system', 'quantity_fact']
        widgets = {
            'product': forms.Select(attrs={'class': 'form-control'}),
            'quantity_system': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.001', 'readonly': True}),
            'quantity_fact': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.001'}),
        }

    def clean_quantity_fact(self):
        quantity_fact = self.cleaned_data.get('quantity_fact')
        if quantity_fact and quantity_fact < 0:
            raise ValidationError('Количество не может быть отрицательным')
        return quantity_fact


# ============================================================================
# TRANSFER FORMS - Перемещение товаров между складами
# ============================================================================

class TransferHeaderForm(forms.ModelForm):
    """
    Форма заголовка документа перемещения товара между складами.
    Содержит информацию о складах-источнике и складе-назначении, примечания.
    """
    class Meta:
        model = TransferDocument
        fields = ['from_warehouse', 'to_warehouse', 'notes']
        widgets = {
            'from_warehouse': forms.Select(attrs={'class': 'form-control'}),
            'to_warehouse': forms.Select(attrs={'class': 'form-control'}),
            'notes': forms.Textarea(attrs={'class': 'form-control', 'rows': 3, 'placeholder': 'Примечания к перемещению'}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Фильтруем только активные склады
        self.fields['from_warehouse'].queryset = Warehouse.objects.filter(is_active=True)
        self.fields['to_warehouse'].queryset = Warehouse.objects.filter(is_active=True)

    def clean(self):
        cleaned_data = super().clean()
        from_warehouse = cleaned_data.get('from_warehouse')
        to_warehouse = cleaned_data.get('to_warehouse')

        if from_warehouse and to_warehouse:
            if from_warehouse.id == to_warehouse.id:
                raise ValidationError('Склад-источник и склад-назначение должны быть разными')

        return cleaned_data


class TransferLineForm(forms.Form):
    """
    Форма для одной строки товара при массовом перемещении.
    Используется в динамической таблице для ввода нескольких товаров.
    """
    product = forms.ModelChoiceField(
        queryset=Product.objects.filter(status='active').order_by('name'),
        widget=forms.Select(attrs={'class': 'form-control'}),
        label="Товар",
        required=True
    )

    quantity = forms.DecimalField(
        max_digits=10,
        decimal_places=3,
        widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.001'}),
        label="Количество",
        required=True
    )

    def clean_quantity(self):
        quantity = self.cleaned_data.get('quantity')
        if quantity and quantity <= 0:
            raise ValidationError('Количество должно быть больше нуля')
        return quantity


class TransferBulkForm(forms.Form):
    """
    Комбинированная форма для ввода перемещения товаров.
    Содержит header информацию (склад-источник, склад-назначение, примечания) + динамический набор товаров.
    """
    from_warehouse = forms.ModelChoiceField(
        queryset=Warehouse.objects.filter(is_active=True),
        widget=forms.Select(attrs={'class': 'form-control'}),
        label="Склад-отгрузки",
        required=True
    )

    to_warehouse = forms.ModelChoiceField(
        queryset=Warehouse.objects.filter(is_active=True),
        widget=forms.Select(attrs={'class': 'form-control'}),
        label="Склад-приемки",
        required=True
    )

    notes = forms.CharField(
        widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3, 'placeholder': 'Примечания к перемещению'}),
        label="Примечания",
        required=False
    )

    def clean(self):
        cleaned_data = super().clean()
        from_warehouse = cleaned_data.get('from_warehouse')
        to_warehouse = cleaned_data.get('to_warehouse')

        if from_warehouse and to_warehouse:
            if from_warehouse.id == to_warehouse.id:
                raise ValidationError('Склад-источник и склад-назначение должны быть разными')

        return cleaned_data


# ============================================================================
# WRITEOFF DOCUMENT FORMS - Документы списания
# ============================================================================

class WriteOffDocumentForm(forms.ModelForm):
    """
    Форма создания/редактирования документа списания.
    """
    class Meta:
        model = WriteOffDocument
        fields = ['warehouse', 'date', 'notes']
        widgets = {
            'warehouse': forms.Select(attrs={'class': 'form-control'}),
            'date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}, format='%Y-%m-%d'),
            'notes': forms.Textarea(attrs={'class': 'form-control', 'rows': 3, 'placeholder': 'Примечания к документу'}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['warehouse'].queryset = Warehouse.objects.filter(is_active=True)
        
        # Отключаем локализацию для поля date, чтобы использовать формат yyyy-MM-dd
        self.fields['date'].input_formats = ['%Y-%m-%d']

        # Если есть склад по умолчанию - предвыбираем его
        if not self.initial.get('warehouse'):
            default_warehouse = Warehouse.objects.filter(
                is_active=True,
                is_default=True
            ).first()
            if default_warehouse:
                self.initial['warehouse'] = default_warehouse.id


class WriteOffDocumentItemForm(forms.ModelForm):
    """
    Форма добавления/редактирования позиции в документ списания.
    """
    class Meta:
        model = WriteOffDocumentItem
        fields = ['product', 'quantity', 'reason', 'notes']
        widgets = {
            'product': forms.Select(attrs={'class': 'form-control'}),
            'quantity': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.001', 'min': '0.001'}),
            'reason': forms.Select(attrs={'class': 'form-control'}),
            'notes': forms.Textarea(attrs={'class': 'form-control', 'rows': 2, 'placeholder': 'Примечания'}),
        }

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

        if document:
            # Фильтруем товары - только те, что есть на складе
            products_with_stock = Stock.objects.filter(
                warehouse=document.warehouse,
                quantity_available__gt=0
            ).values_list('product_id', flat=True)

            self.fields['product'].queryset = Product.objects.filter(
                id__in=products_with_stock,
                status='active'
            ).order_by('name')
        else:
            self.fields['product'].queryset = Product.objects.filter(
                status='active'
            ).order_by('name')

    def clean_quantity(self):
        quantity = self.cleaned_data.get('quantity')
        if quantity and quantity <= 0:
            raise ValidationError('Количество должно быть больше нуля')
        return quantity

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

        if product and quantity and self.document:
            stock = Stock.objects.filter(
                product=product,
                warehouse=self.document.warehouse
            ).first()

            if not stock:
                raise ValidationError({
                    'product': f'Товар "{product.name}" отсутствует на складе'
                })

            available = stock.quantity_available - stock.quantity_reserved

            # Учитываем текущий резерв при редактировании
            if self.instance.pk and self.instance.reservation:
                available += self.instance.reservation.quantity

            if quantity > available:
                raise ValidationError({
                    'quantity': f'Недостаточно свободного товара. '
                               f'Доступно: {available}, запрашивается: {quantity}'
                })

        return cleaned_data


class IncomingDocumentForm(forms.ModelForm):
    """
    Форма создания/редактирования документа поступления.
    """
    class Meta:
        model = IncomingDocument
        fields = ['warehouse', 'date', 'receipt_type', 'supplier_name', 'notes']
        widgets = {
            'warehouse': forms.Select(attrs={'class': 'form-control'}),
            'date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}, format='%Y-%m-%d'),
            'receipt_type': forms.Select(attrs={'class': 'form-control'}),
            'supplier_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Наименование поставщика'}),
            'notes': forms.Textarea(attrs={'class': 'form-control', 'rows': 3, 'placeholder': 'Примечания к документу'}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['warehouse'].queryset = Warehouse.objects.filter(is_active=True)
        
        # Отключаем локализацию для поля date, чтобы использовать формат yyyy-MM-dd
        self.fields['date'].input_formats = ['%Y-%m-%d']

        # Если есть склад по умолчанию - предвыбираем его
        if not self.initial.get('warehouse'):
            default_warehouse = Warehouse.objects.filter(
                is_active=True,
                is_default=True
            ).first()
            if default_warehouse:
                self.initial['warehouse'] = default_warehouse.id

        # Устанавливаем тип поступления по умолчанию
        if not self.initial.get('receipt_type'):
            self.initial['receipt_type'] = 'supplier'

    def clean(self):
        cleaned_data = super().clean()
        receipt_type = cleaned_data.get('receipt_type')
        supplier_name = cleaned_data.get('supplier_name')

        # Для типа 'supplier' supplier_name обязателен
        if receipt_type == 'supplier' and not supplier_name:
            raise ValidationError({
                'supplier_name': 'Для типа "Поступление от поставщика" необходимо указать наименование поставщика'
            })

        # Для других типов supplier_name не нужен
        if receipt_type != 'supplier' and supplier_name:
            cleaned_data['supplier_name'] = None

        return cleaned_data


class IncomingDocumentItemForm(forms.ModelForm):
    """
    Форма добавления/редактирования позиции в документ поступления.
    """
    class Meta:
        model = IncomingDocumentItem
        fields = ['product', 'quantity', 'cost_price', 'notes']
        widgets = {
            'product': forms.Select(attrs={'class': 'form-control'}),
            'quantity': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.001', 'min': '0.001'}),
            'cost_price': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01', 'min': '0'}),
            'notes': forms.Textarea(attrs={'class': 'form-control', 'rows': 2, 'placeholder': 'Примечания'}),
        }

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

        # Для поступлений можно выбрать любой активный товар (не нужно проверять наличие на складе)
        self.fields['product'].queryset = Product.objects.filter(
            status='active'
        ).order_by('name')

    def clean_quantity(self):
        quantity = self.cleaned_data.get('quantity')
        if quantity and quantity <= 0:
            raise ValidationError('Количество должно быть больше нуля')
        return quantity

    def clean_cost_price(self):
        cost_price = self.cleaned_data.get('cost_price')
        if cost_price is not None and cost_price < 0:
            raise ValidationError('Закупочная цена не может быть отрицательной')
        return cost_price


# ==================== TRANSFORMATION FORMS ====================

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

    class Meta:
        model = Transformation
        fields = ['warehouse', 'comment']
        widgets = {
            'warehouse': forms.Select(attrs={'class': 'form-select'}),
            'comment': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 3,
                'placeholder': 'Комментарий (необязательно)'
            }),
        }


class TransformationInputForm(forms.Form):
    """Форма для добавления входного товара в трансформацию"""

    product = forms.ModelChoiceField(
        queryset=Product.objects.filter(status='active').order_by('name'),
        label='Товар (что списываем)',
        widget=forms.Select(attrs={
            'class': 'form-select',
            'id': 'id_input_product'
        })
    )
    quantity = forms.DecimalField(
        label='Количество',
        min_value=Decimal('0.001'),
        max_digits=10,
        decimal_places=3,
        widget=forms.NumberInput(attrs={
            'class': 'form-control',
            'step': '0.001',
            'placeholder': '0.000',
            'id': 'id_input_quantity'
        })
    )

    def __init__(self, *args, **kwargs):
        self.transformation = kwargs.pop('transformation', None)
        super().__init__(*args, **kwargs)

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

        if product and quantity:
            # Проверяем что товар еще не добавлен
            if self.transformation and self.transformation.inputs.filter(product=product).exists():
                raise ValidationError(f'Товар "{product.name}" уже добавлен в качестве входного')

        return cleaned_data


class TransformationOutputForm(forms.Form):
    """Форма для добавления выходного товара в трансформацию"""

    product = forms.ModelChoiceField(
        queryset=Product.objects.filter(status='active').order_by('name'),
        label='Товар (что получаем)',
        widget=forms.Select(attrs={
            'class': 'form-select',
            'id': 'id_output_product'
        })
    )
    quantity = forms.DecimalField(
        label='Количество',
        min_value=Decimal('0.001'),
        max_digits=10,
        decimal_places=3,
        widget=forms.NumberInput(attrs={
            'class': 'form-control',
            'step': '0.001',
            'placeholder': '0.000',
            'id': 'id_output_quantity'
        })
    )

    def __init__(self, *args, **kwargs):
        self.transformation = kwargs.pop('transformation', None)
        super().__init__(*args, **kwargs)

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

        if product and quantity:
            # Проверяем что товар еще не добавлен
            if self.transformation and self.transformation.outputs.filter(product=product).exists():
                raise ValidationError(f'Товар "{product.name}" уже добавлен в качестве выходного')
            
            # Проверяем что сумма выходных не превышает сумму входных
            if self.transformation:
                total_input = sum(
                    trans_input.quantity for trans_input in self.transformation.inputs.all()
                )
                total_output_existing = sum(
                    trans_output.quantity for trans_output in self.transformation.outputs.all()
                )
                total_output_new = total_output_existing + quantity
                
                if total_output_new > total_input:
                    raise ValidationError(
                        f'Сумма выходных количеств ({total_output_new}) не может превышать '
                        f'сумму входных количеств ({total_input}). '
                        f'Максимально можно добавить: {total_input - total_output_existing}'
                    )

        return cleaned_data

