from django.shortcuts import render, redirect, get_object_or_404
from apps.estoque.forms import CategoriaInsumoForm, ItemEstoqueForm, MovimentacaoEstoqueForm
from apps.estoque.models import CategoriaInsumo, ItemEstoque, MovimentacaoEstoque
from django.contrib import messages
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from apps.dashboard.utils import get_user_info
from django.contrib.auth.decorators import login_required
from django.db.models import Sum, F, FloatField
from django.utils import timezone
from datetime import timedelta

@csrf_exempt
def criar_categoria_insumo_ajax(request):
    print("View 'criar_categoria_insumo_ajax' called")
    print("Request method:", request.method)
    if request.method == 'POST':
        print("POST data:", request.POST)
        form = CategoriaInsumoForm(request.POST)
        if form.is_valid():
            print("Form is valid")
            categoria = form.save()
            print("Categoria criada:", categoria)
            return JsonResponse({
                "success": True,
                "message": "Categoria criada com sucesso!",
                "categoria_id": categoria.id,
                "categoria_nome": categoria.nome
            })
        else:
            print("Form errors:", form.errors)
            return JsonResponse({"success": False, "errors": form.errors})
    else:
        print("Invalid method")
    return JsonResponse({"success": False, "message": "Método inválido"})

def criar_categoria_insumo(request):
    if not request.user.is_authenticated:
        return redirect('index')
    user_info = get_user_info(request.user.id)
    if request.method == 'POST':
        form = CategoriaInsumoForm(request.POST)
        if form.is_valid():
            form.save()
            messages.success(request, "Categoria criada com sucesso.")
            return redirect('lista_categorias_insumo')
    else:
        form = CategoriaInsumoForm()
    return render(request, 'estoque/criar_categoria_insumo.html', {'form': form, 'user_info': user_info})

def lista_categorias_insumo(request):
    if not request.user.is_authenticated:
        return redirect('index')
    user_info = get_user_info(request.user.id)
    categorias = CategoriaInsumo.objects.all()
    return render(request, 'estoque/lista_categorias_insumo.html', {'categorias': categorias, 'user_info': user_info})

def criar_item_estoque(request):
    if not request.user.is_authenticated:
        return redirect('index')
    user_info = get_user_info(request.user.id)
    if request.method == 'POST':
        form = ItemEstoqueForm(request.POST)
        if form.is_valid():
            form.save()
            messages.success(request, "Item de estoque criado com sucesso.")
            return redirect('lista_itens_estoque')
    else:
        form = ItemEstoqueForm()
    return render(request, 'estoque/criar_item_estoque.html', {'form': form, 'user_info': user_info})

def lista_itens_estoque(request):
    if not request.user.is_authenticated:
        return redirect('index')
    user_info = get_user_info(request.user.id)

    categoria_id = request.GET.get('categoria')
    categorias = CategoriaInsumo.objects.all()
    hoje = timezone.now().date()
    proximos_30_dias = hoje + timedelta(days=30)

    # Defina 'itens' antes de usá-la
    if categoria_id:
        itens = ItemEstoque.objects.filter(categoria_id=categoria_id, quantidade__gt=0)
    else:
        itens = ItemEstoque.objects.filter(quantidade__gt=0)

    # Adiciona atributos para indicar se o item está vencido ou próximo do vencimento
    for item in itens:
        if item.data_validade:
            if item.data_validade < hoje:
                item.vencido = True
                item.proximo_vencimento = False
            elif hoje <= item.data_validade <= proximos_30_dias:
                item.vencido = False
                item.proximo_vencimento = True
            else:
                item.vencido = False
                item.proximo_vencimento = False
        else:
            # Caso o item não tenha data de validade, consideramos como não vencido
            item.vencido = False
            item.proximo_vencimento = False

    context = {
        'itens': itens,
        'categorias': categorias,
        'categoria_selecionada': int(categoria_id) if categoria_id else None,
        'user_info': user_info,
    }
    return render(request, 'estoque/lista_itens_estoque.html', context)



def editar_item_estoque(request, item_id):
    if not request.user.is_authenticated:
        return redirect('index')
    user_info = get_user_info(request.user.id)
    item = get_object_or_404(ItemEstoque, pk=item_id)
    if request.method == 'POST':
        form = ItemEstoqueForm(request.POST, instance=item)
        if form.is_valid():
            form.save()
            messages.success(request, "Item de estoque atualizado com sucesso.")
            return redirect('lista_itens_estoque')
    else:
        form = ItemEstoqueForm(instance=item)
    return render(request, 'estoque/editar_item_estoque.html', {'form': form, 'item': item, 'user_info': user_info})

def deletar_item_estoque(request, item_id):
    if not request.user.is_authenticated:
        return redirect('index')
    try:
        item = ItemEstoque.objects.get(pk=item_id)
        item.delete()
        messages.success(request, "Item de estoque excluído com sucesso.")
    except ItemEstoque.DoesNotExist:
        messages.error(request, "Item de estoque não encontrado.")
    return redirect('lista_itens_estoque')

@login_required
def registrar_movimentacao(request):
    if not request.user.is_authenticated:
        return redirect('index')
    user_info = get_user_info(request.user.id)
    item_id = request.GET.get('item_id')
    initial_data = {}
    if item_id:
        item = get_object_or_404(ItemEstoque, pk=item_id)
        initial_data['item'] = item

    if request.method == 'POST':
        form = MovimentacaoEstoqueForm(request.POST)
        if form.is_valid():
            movimentacao = form.save(commit=False)
            movimentacao.responsavel = request.user
            try:
                movimentacao.save()
                messages.success(request, "Movimentação registrada com sucesso.")
                return redirect('lista_itens_estoque')
            except ValueError as e:
                form.add_error(None, str(e))
    else:
        form = MovimentacaoEstoqueForm(initial=initial_data)
    return render(request, 'estoque/registrar_movimentacao.html', {'form': form, 'user_info': user_info})

@login_required
def lista_movimentacoes(request):
    if not request.user.is_authenticated:
        return redirect('index')
    user_info = get_user_info(request.user.id)
    movimentacoes = MovimentacaoEstoque.objects.order_by('-data')
    return render(request, 'estoque/lista_movimentacoes.html', {'movimentacoes': movimentacoes, 'user_info': user_info})

def relatorio_insumos_por_categoria(request):
    if not request.user.is_authenticated:
        return redirect('index')
    user_info = get_user_info(request.user.id)

    # Agrega a quantidade e o custo total por categoria
    categoria_data = CategoriaInsumo.objects.annotate(
        total_quantidade=Sum('itens__quantidade'),
        total_custo=Sum(
            F('itens__quantidade') * F('itens__custo_unitario'),
            output_field=FloatField()
        )
    )

    context = {
        'categoria_data': categoria_data,
        'user_info': user_info,
    }
    return render(request, 'estoque/relatorio_insumos_por_categoria.html', context)

def itens_proximos_vencimento(request):
    if not request.user.is_authenticated:
        return redirect('index')
    user_info = get_user_info(request.user.id)

    hoje = timezone.now().date()
    proximos_30_dias = hoje + timedelta(days=30)

    itens_vencendo = ItemEstoque.objects.filter(
        data_validade__range=(hoje, proximos_30_dias)
    ).annotate(
        dias_restantes=F('data_validade') - hoje
    )

    # Calcula os dias restantes para cada item
    for item in itens_vencendo:
        item.dias_restantes = (item.data_validade - hoje).days

    context = {
        'itens_vencendo': itens_vencendo,
        'user_info': user_info,
    }
    return render(request, 'estoque/itens_proximos_vencimento.html', context)

def relatorio_custos_insumos(request):
    if not request.user.is_authenticated:
        return redirect('index')
    user_info = get_user_info(request.user.id)

    # Anota o custo total de cada item
    itens = ItemEstoque.objects.annotate(
        custo_total=F('quantidade') * F('custo_unitario')
    )

    # Calcula o custo total por categoria
    categorias = CategoriaInsumo.objects.annotate(
        total_custo=Sum(
            F('itens__quantidade') * F('itens__custo_unitario'),
            output_field=FloatField()
        )
    )

    # Calcula o custo total geral
    total_custo_geral = itens.aggregate(
        total_custo=Sum('custo_total')
    )['total_custo'] or 0

    context = {
        'itens': itens,
        'categorias': categorias,
        'total_custo_geral': total_custo_geral,
        'user_info': user_info,
    }
    return render(request, 'estoque/relatorio_custos_insumos.html', context)