from django.shortcuts import render, redirect, get_object_or_404
from apps.dashboard.utils import get_user_info
from apps.repique.forms import RepiqueForm
from django.contrib import messages
from apps.lotes.models import Semeadura
from apps.funcionario.models import Funcionario, Cargo
from apps.repique.models import Repique, LogFinalizacaoRepique
from datetime import datetime
from django.db.models import Sum, Max
from django.http import JsonResponse
from django.db.models import Exists, OuterRef
from django.utils import timezone
from django.utils.safestring import mark_safe
from django.db.models import Prefetch
from datetime import date
from django.views.decorators.http import require_POST

def lista_repique_completa(request):
    if not request.user.is_authenticated:
        return redirect('index')

    user_info = get_user_info(request.user.id)

    # Captura dos parâmetros de ano e mês
    ano_filtro = request.GET.get('ano')
    mes_filtro = request.GET.get('mes')

    # Lista estática de meses
    meses = [
        {'numero': 1, 'nome': 'Janeiro'},
        {'numero': 2, 'nome': 'Fevereiro'},
        {'numero': 3, 'nome': 'Março'},
        {'numero': 4, 'nome': 'Abril'},
        {'numero': 5, 'nome': 'Maio'},
        {'numero': 6, 'nome': 'Junho'},
        {'numero': 7, 'nome': 'Julho'},
        {'numero': 8, 'nome': 'Agosto'},
        {'numero': 9, 'nome': 'Setembro'},
        {'numero': 10, 'nome': 'Outubro'},
        {'numero': 11, 'nome': 'Novembro'},
        {'numero': 12, 'nome': 'Dezembro'},
    ]

    # Definir o queryset base de Semeadura com as anotações necessárias
    semeaduras_query = Semeadura.objects.annotate(
        total_repicado=Sum('repiques__quantidade_repicada'),
        ultima_data_repique=Max('repiques__data_repique')
    ).select_related('lote__especie')

    # Aplicar filtros por ano e mês na data_repique dos repiques relacionados
    if ano_filtro:
        if mes_filtro:
            # Filtra por ano e mês na data_repique
            semeaduras_query = semeaduras_query.filter(
                repiques__data_repique__year=ano_filtro,
                repiques__data_repique__month=mes_filtro
            )
        else:
            # Filtra apenas por ano na data_repique
            semeaduras_query = semeaduras_query.filter(
                repiques__data_repique__year=ano_filtro
            )

    # Prefetch repiques relacionados aplicando os filtros de data_repique
    if ano_filtro or mes_filtro:
        repique_filter = {}
        if ano_filtro:
            repique_filter['data_repique__year'] = ano_filtro
        if mes_filtro:
            repique_filter['data_repique__month'] = mes_filtro

        semeaduras_query = semeaduras_query.prefetch_related(
            Prefetch(
                'repiques',
                queryset=Repique.objects.filter(**repique_filter),
                to_attr='filtrados_repiques'  # Nome do atributo para acessar os repiques filtrados
            )
        )
    else:
        # Prefetch todos os repiques se nenhum filtro for aplicado
        semeaduras_query = semeaduras_query.prefetch_related('repiques')

    semeaduras = semeaduras_query.distinct()

    # Obtenha os anos disponíveis para o filtro com base em data_repique
    anos_disponiveis = Repique.objects.dates('data_repique', 'year').distinct()

    repiques = []

    for semeadura in semeaduras:
        # Utilize 'filtrados_repiques' se filtros foram aplicados, caso contrário, 'repiques'
        repiques_relacionados = getattr(semeadura, 'filtrados_repiques', semeadura.repiques.all())

        repiques_data = []
        repiques_quantidades = []
        repiques_ids = []
        repiques_finalizado = []

        for repique in repiques_relacionados:
            repiques_data.append(repique.data_repique.strftime('%d/%m/%Y'))
            repiques_quantidades.append(str(repique.quantidade_repicada))
            repiques_ids.append(repique.id)
            repiques_finalizado.append(repique.finalizado)

        # Certifique-se de que essas variáveis são sempre listas
        repiques_data = repiques_data if repiques_data else [""]
        repiques_quantidades = repiques_quantidades if repiques_quantidades else [""]
        repiques_ids = repiques_ids if repiques_ids else [""]
        repiques_finalizado = repiques_finalizado if repiques_finalizado else [False]

        repiques.append({
            'semeadura_id': semeadura.id,
            'numero_muda': semeadura.numero_muda,
            'data_semeia': semeadura.data_semeia,
            'nome_popular': semeadura.lote.especie.nome_popular,
            'especies': semeadura.lote.especie.especies,
            'ultima_data_repique': semeadura.ultima_data_repique,
            'total_repicado': semeadura.total_repicado,
            'repique_dates': repiques_data,
            'repique_quantities': repiques_quantidades,
            'repique_ids': repiques_ids,
            'finalizado': repiques_finalizado,
            'estimativa_minima': semeadura.lote.estimativa_minima,
            'estimativa_maxima': semeadura.lote.estimativa_maxima,
            'estimativa_media': semeadura.lote.estimativa_media,  # Corrigido para 'estimativa_media'
            'nova_media': semeadura.nova_media,
        })

    return render(request, 'repique/lista_repique_completa.html', {
        'semeaduras': semeaduras,
        'repiques': repiques,
        'anos_disponiveis': anos_disponiveis,
        'ano_filtro': ano_filtro,
        'mes_filtro': mes_filtro,
        'meses': meses,
        'user_info': user_info
    })


def lista_repique(request):
    user_info = get_user_info(request.user.id)

    # Filtra apenas funcionários com o cargo 'Repique' e que não sejam o admin
    funcionarios = Funcionario.objects.filter(
        cargo__nome__iexact='Repique'
    ).exclude(usuariofuncionario__usuario__username='admin').distinct()

    semeaduras = Semeadura.objects.annotate(
        total_repicado=Sum('repiques__quantidade_repicada'),
        ultima_data_repique=Max('repiques__data_repique')
    ).select_related('lote__especie').filter(
        ~Exists(Repique.objects.filter(semeadura=OuterRef('pk'), finalizado=True))
    )

    repiques = []

    for semeadura in semeaduras:
        repiques_data = []
        repiques_quantidades = []
        repiques_ids = []
        repiques_finalizado = []
        repique_nomes_funcionarios = []

        for repique in semeadura.repiques.all():
            repiques_data.append(repique.data_repique.strftime('%d/%m/%Y'))
            repiques_quantidades.append(str(repique.quantidade_repicada))
            repiques_ids.append(repique.id)
            repiques_finalizado.append(repique.finalizado)
            nome_funcionario = repique.funcionario.nome_completo if repique.funcionario else "Não informado"
            repique_nomes_funcionarios.append(nome_funcionario)

        total_repicado = semeadura.total_repicado
        nova_media = semeadura.nova_media
        show_alert = False

        if total_repicado is not None and nova_media is not None:
            total_repicado_int = int(total_repicado)
            nova_media_int = int(nova_media * 1000)
            show_alert = total_repicado_int >= nova_media_int

        repiques.append({
            'semeadura_id': semeadura.id,
            'numero_muda': semeadura.numero_muda,
            'data_semeia': semeadura.data_semeia,
            'nome_popular': semeadura.lote.especie.nome_popular,
            'especies': semeadura.lote.especie.especies,
            'ultima_data_repique': semeadura.ultima_data_repique,
            'total_repicado': semeadura.total_repicado,
            'qtd_sementes_utilizada': semeadura.qtd_sementes_utilizada,
            'repique_dates': repiques_data or [""],
            'repique_quantities': repiques_quantidades or [""],
            'repique_ids': repiques_ids or [""],
            'finalizado': repiques_finalizado,
            'estimativa_minima': semeadura.lote.estimativa_minima,
            'estimativa_maxima': semeadura.lote.estimativa_maxima,
            'estimativa_media': semeadura.lote.estimativa_media,
            'nova_media': semeadura.nova_media,
            'show_alert': show_alert,
            'funcionarios': funcionarios,
            'repique_funcionarios': repique_nomes_funcionarios,
        })

    return render(request, 'repique/lista_repique.html', {
        'semeaduras': semeaduras,
        'repiques': repiques,
        'user_info': user_info,
        'funcionarios': funcionarios
    })


@require_POST
def excluir_repique(request, repique_id):
    if request.headers.get('x-requested-with') == 'XMLHttpRequest':
        try:
            repique = Repique.objects.get(pk=repique_id)
            repique.delete()
            return JsonResponse({'message': 'Repique excluído com sucesso.'}, status=200)
        except Repique.DoesNotExist:
            return JsonResponse({'message': 'Repique não encontrado.'}, status=404)
        except Exception as e:
            return JsonResponse({'message': f'Erro ao excluir repique: {str(e)}'}, status=500)
    return JsonResponse({'message': 'Requisição inválida.'}, status=400)


from django.http import JsonResponse

def repique(request, semeadura_id):
    semeadura = get_object_or_404(Semeadura, pk=semeadura_id)

    if request.method == 'POST' and request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        form = RepiqueForm(request.POST)
        funcionario_id = request.POST.get('funcionario')
        data_repique_str = request.POST.get('data_repique')

        if form.is_valid() and funcionario_id and data_repique_str:
            try:
                data_repique = datetime.strptime(data_repique_str, '%Y-%m-%d').date()
            except ValueError:
                return JsonResponse({'status': 'error', 'message': 'Data do repique inválida.'})

            ja_feito = Repique.objects.filter(
                funcionario_id=funcionario_id,
                semeadura=semeadura,
                data_repique=data_repique
            ).exists()

            if ja_feito:
                return JsonResponse(
                    {'status': 'duplicado', 'message': 'Repique já registrado por esse funcionário nesta data e lote.'},
                     status=200
                )

            repique = form.save(commit=False)
            repique.registrado_por = request.user
            repique.semeadura = semeadura
            repique.funcionario = Funcionario.objects.get(id=funcionario_id)
            repique.data_repique = data_repique
            repique.save()

            return JsonResponse({'status': 'success', 'message': 'Repique registrado com êxito.'})

        return JsonResponse({'status': 'error', 'message': 'Formulário inválido ou dados ausentes.'})

    return JsonResponse({'status': 'error', 'message': 'Requisição inválida.'})





def finalizar_repique(request, semeadura_id):
    try:
        if request.method == 'POST':
            semeadura = Semeadura.objects.get(pk=semeadura_id)

            # Adicione a definição de motivo_exclusao e motivo_exclusao_outros aqui
            motivo_exclusao = request.POST.get('motivo_exclusao', '')  # Substitua 'motivo_exclusao' com o nome correto do campo no seu formulário
            motivo_exclusao_outros = request.POST.get('motivo_exclusao_outros', '')  # Substitua 'motivo_exclusao_outros' com o nome correto do campo no seu formulário

            # Exemplo de verificação e definição de motivo_final
            if motivo_exclusao == 'Outros' and motivo_exclusao_outros:
                motivo_final = motivo_exclusao_outros
            else:
                motivo_final = motivo_exclusao

            LogFinalizacaoRepique.objects.create(
                numero_lote=semeadura.numero_muda,
                data_lote=semeadura.data_semeia,
                semeadura_id=semeadura_id,
                data_exclusao=timezone.now(),
                hora_exclusao=timezone.now(),
                usuario_exclusao=request.user,
                nome_usuario_exclusao=request.user.username,
                motivo_exclusao=motivo_final,
                motivo_exclusao_outros=motivo_exclusao_outros
            )

            Repique.objects.filter(semeadura_id=semeadura_id).update(finalizado=True)
            messages.success(request, mark_safe(
                    '<i class="fa-solid fa-circle-check"></i><strong class="mx-1">Sucesso!</strong> Repique finalizado com êxito.'))

            return JsonResponse({'status': 'success', 'message': 'Repique finalizado com sucesso.'})

        elif request.method == 'GET':
            return JsonResponse({'status': 'success', 'message': 'Solicitação GET permitida para esta view.'})

    except Exception as e:
        print(f'Erro na view finalizar_repique: {e}')
        return JsonResponse({'status': 'error', 'message': 'Erro interno no servidor.'}, status=500)

    return JsonResponse({'status': 'error', 'message': 'Método não suportado.'})

def repique_data_ajax(request):
    repiques = Repique.objects.all().select_related('semeadura')
    data = []
    for repique in repiques:
        data.append({
            'numero_muda': repique.semeadura.numero_muda,
            'data_semeia': repique.semeadura.data_semeia.strftime('%d/%m/%Y'),
            'nome_especie': f"{repique.nome_popular} + {repique.especies}",
            'ultima_data_repique': repique.data_repique.strftime('%d/%m/%Y') if repique.data_repique else 'N/A',
            'total_repicado': repique.total_repicado or 0,
            'qtd_sementes_utilizada': repique.qtd_sementes_utilizada,
            'acoes': render_to_string('partials/acoes_repique.html', {'repique': repique}, request=request)
        })
    return JsonResponse(data, safe=False)
