# -*- coding: utf-8 -*-
"""
Transfer (Перемещение товара между складами) views
GROUP 2: MEDIUM PRIORITY
"""
import json
from decimal import Decimal
from django.views.generic import ListView, CreateView, UpdateView, DeleteView, DetailView
from django.views import View
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages
from django.http import JsonResponse
from django.db import transaction
from django.shortcuts import redirect, render
from ..models import TransferDocument, TransferDocumentItem, Stock
from ..forms import TransferBulkForm
from inventory.utils.document_generator import generate_transfer_document_number
from inventory.services.batch_manager import StockBatchManager
from products.models import Product


class TransferListView(LoginRequiredMixin, ListView):
    """
    View для просмотра списка документов перемещений товаров.
    """
    model = TransferDocument
    template_name = 'inventory/transfer/transfer_list.html'
    context_object_name = 'transfers'
    paginate_by = 20

    def get_queryset(self):
        return TransferDocument.objects.select_related(
            'from_warehouse', 'to_warehouse'
        ).order_by('-created_at')


# ============================================================================
# VIEWS ДЛЯ ПЕРЕМЕЩЕНИЯ ТОВАРОВ (TransferDocument + TransferDocumentItem)
# ============================================================================

class TransferBulkCreateView(LoginRequiredMixin, View):
    """
    View для создания документа перемещения товаров между складами с FIFO логикой.
    Один документ может содержать несколько товаров.
    """
    template_name = 'inventory/transfer/transfer_bulk_form.html'

    def get(self, request):
        from products.models import Product
        form = TransferBulkForm()
        products = Product.objects.filter(status='active').values('id', 'name', 'sku').order_by('name')
        return render(request, self.template_name, {
            'form': form,
            'products': products
        })

    def post(self, request):
        form = TransferBulkForm(request.POST)

        if not form.is_valid():
            messages.error(request, 'Ошибка при заполнении формы')
            return render(request, self.template_name, {'form': form}, status=400)

        # Получаем данные из формы
        from_warehouse = form.cleaned_data.get('from_warehouse')
        to_warehouse = form.cleaned_data.get('to_warehouse')
        notes = form.cleaned_data.get('notes', '')

        # Парсим JSON с товарами
        products_json = request.POST.get('products_json', '[]')
        try:
            products_data = json.loads(products_json)
        except json.JSONDecodeError:
            messages.error(request, 'Ошибка при парсинге товаров. Пожалуйста, проверьте данные.')
            return render(request, self.template_name, {'form': form}, status=400)

        # Проверяем что товары есть
        if not products_data:
            messages.error(request, 'Необходимо добавить хотя бы один товар для перемещения.')
            return render(request, self.template_name, {'form': form}, status=400)

        # Валидируем товары
        products = []
        for item in products_data:
            product_id = item.get('product_id')
            quantity = Decimal(str(item.get('quantity', 0)))

            if quantity <= 0:
                messages.error(request, f'Количество товара должно быть больше нуля')
                return render(request, self.template_name, {'form': form}, status=400)

            try:
                product = Product.objects.get(id=product_id, status='active')
                products.append((product, quantity))
            except Product.DoesNotExist:
                messages.error(request, f'Товар с ID {product_id} не найден или неактивен')
                return render(request, self.template_name, {'form': form}, status=400)

        # Начинаем транзакцию
        try:
            with transaction.atomic():
                # 1. Создаем документ TransferDocument
                transfer_document = TransferDocument.objects.create(
                    from_warehouse=from_warehouse,
                    to_warehouse=to_warehouse,
                    document_number=generate_transfer_document_number(),
                    notes=notes
                )

                # 2. Для каждого товара выполняем FIFO перемещение
                for product, quantity in products:
                    try:
                        # Получаем список распределений по FIFO
                        transfers = StockBatchManager.transfer_product_by_fifo(
                            product=product,
                            from_warehouse=from_warehouse,
                            to_warehouse=to_warehouse,
                            quantity=quantity
                        )

                        # Создаем TransferDocumentItem для каждого использованного batch
                        for source_batch, qty_transferred, new_batch in transfers:
                            TransferDocumentItem.objects.create(
                                transfer_document=transfer_document,
                                product=product,
                                batch=source_batch,
                                quantity=qty_transferred,
                                new_batch=new_batch
                            )

                    except ValueError as e:
                        messages.error(request, f'Ошибка при перемещении товара "{product.name}": {str(e)}')
                        raise  # Откатываем транзакцию

                # 3. Успешно создали документ
                messages.success(
                    request,
                    f'Документ перемещения {transfer_document.document_number} успешно создан. '
                    f'Перемещено {len(products)} видов товаров.'
                )

                return redirect('inventory:transfer-detail', pk=transfer_document.id)

        except Exception as e:
            messages.error(request, f'Ошибка при создании документа перемещения: {str(e)}')
            return render(request, self.template_name, {'form': form}, status=400)


class TransferDetailView(LoginRequiredMixin, DetailView):
    """
    View для просмотра деталей документа перемещения.
    """
    model = TransferDocument
    template_name = 'inventory/transfer/transfer_detail.html'
    context_object_name = 'transfer_document'

    def get_queryset(self):
        return TransferDocument.objects.select_related(
            'from_warehouse', 'to_warehouse'
        ).prefetch_related(
            'items__product', 'items__batch', 'items__new_batch'
        )

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        transfer_document = self.object

        # Собираем статистику по документу
        items = transfer_document.items.all()
        total_items = items.count()
        total_qty = sum(Decimal(str(item.quantity)) for item in items)

        context['total_items'] = total_items
        context['total_qty'] = total_qty
        context['items'] = items

        return context


class TransferDeleteView(LoginRequiredMixin, DeleteView):
    """
    View для удаления документа перемещения.
    """
    model = TransferDocument
    template_name = 'inventory/transfer/transfer_confirm_delete.html'
    success_url = reverse_lazy('inventory:transfer-list')

    def form_valid(self, form):
        transfer_document = self.get_object()
        messages.success(self.request, f'Документ перемещения {transfer_document.document_number} удалён.')
        return super().form_valid(form)


class GetProductStockView(LoginRequiredMixin, View):
    """
    API endpoint для получения доступного количества товара на конкретном складе.
    GET параметры: product_id, warehouse_id
    Возвращает JSON: {"quantity": "100.000", "warehouse_name": "Основной склад"}
    """
    def get(self, request):
        product_id = request.GET.get('product_id')
        warehouse_id = request.GET.get('warehouse_id')

        if not product_id or not warehouse_id:
            return JsonResponse({
                'error': 'Missing required parameters: product_id, warehouse_id'
            }, status=400)

        try:
            product_id = int(product_id)
            warehouse_id = int(warehouse_id)
        except ValueError:
            return JsonResponse({
                'error': 'Invalid parameter values'
            }, status=400)

        try:
            stock = Stock.objects.get(product_id=product_id, warehouse_id=warehouse_id)
            return JsonResponse({
                'quantity': str(stock.quantity_available),
                'warehouse_name': stock.warehouse.name,
                'success': True
            })
        except Stock.DoesNotExist:
            return JsonResponse({
                'quantity': '0.000',
                'warehouse_name': '',
                'success': True
            })
        except Exception as e:
            import traceback
            traceback.print_exc()
            return JsonResponse({
                'error': str(e),
                'success': False
            }, status=500)
