import datetime
import json

from django.contrib import messages
from django.db.models import Sum
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from openpyxl.styles.builtins import total

from Consultas.models import Extenos
from Facturacion.models import tipoServicio, OrdenPago, DetalleOrden, Clientes, NotaCredito, DetalleNotaCredito
from Oficios.models import TipoDocumento
from TransitoApp.snnipers import render_to_pdf
import calendar

from sri.models import Configuracion
from sri.views import generar_xml


# Create your views here.

def buscar_servicio(request):
    data = []
    avaluo = ""
    tonelaje = ""
    tipo = tipoServicio.objects.filter(descripcion__icontains=request.GET.get('q'), estado=True)
    print(request.GET)
    if request.GET.get('a'):
        avaluo = float(request.GET.get('a'))
        if avaluo >= 0 and avaluo <= 4000:
            tipo = tipo.filter(avaluo__desde=0, avaluo__hasta=4000)
        elif avaluo >= 4001 and avaluo <= 8000:
            tipo = tipo.filter(avaluo__desde=4001, avaluo__hasta=8000)
        elif avaluo >= 8001 and avaluo <= 12000:
            tipo = tipo.filter(avaluo__desde=8001, avaluo__hasta=12000)
        elif avaluo >= 12001 and avaluo <= 16000:
            tipo = tipo.filter(avaluo__desde=12001, avaluo__hasta=16000)
        elif avaluo >= 16001 and avaluo <= 20000:
            tipo = tipo.filter(avaluo__desde=16001, avaluo__hasta=20000)
        elif avaluo >= 20001 and avaluo <= 30000:
            tipo = tipo.filter(avaluo__desde=21001, avaluo__hasta=30000)
        elif avaluo >= 30001 and avaluo <= 40000:
            tipo = tipo.filter(avaluo__desde=31001, avaluo__hasta=40000)
        elif avaluo >= 40001:
            tipo = tipo.filter(avaluo__desde=40000, avaluo__hasta=0)
    if request.GET.get('t'):
        tonelaje = float(request.GET.get('t'))
        if tonelaje >= 0 and tonelaje <= 3.5:
            tipo = tipo.filter(tonelaje__desde=0, tonelaje__hasta=3.5)
        elif tonelaje >= 3.51 and tonelaje <= 10:
            tipo = tipo.filter(tonelaje__desde=3.51, tonelaje__hasta=10)
        elif tonelaje >= 10.10 and tonelaje <= 20:
            tipo = tipo.filter(tonelaje__desde=10.10, tonelaje__hasta=20)
        elif tonelaje >= 20.10:
            tipo = tipo.filter(tonelaje__desde=20.10, tonelaje__hasta=100)

    for i in tipo:
        try:
            data.append({
                'pk': i.id,
                'descripcion': i.descripcion,
                'costo': float(i.costo),
                'administrativo': float(i.administrativo),
                'avaluo': "%s - %s" % (i.avaluo.desde, i.avaluo.hasta),
                'tonelaje': "%s - %s" % (i.tonelaje.desde, i.tonelaje.hasta),
                'total': float(i.total)
            })
        except:
            data.append({
                'pk': i.id,
                'descripcion': i.descripcion,
                'costo': float(i.costo),
                'administrativo': float(i.administrativo),
                'avaluo': "",
                'tonelaje': "",
                'total': float(i.total)
            })
    print(data)
    return HttpResponse(json.dumps(data), content_type="application/json")


def orden_pago(request):
    contexto = {
        'fecha': datetime.datetime.now().date()
    }
    return render(request, 'facturacion/orden_pago.html', contexto)


@csrf_exempt
def registrar_orden(request):
    if request.GET:
        nota=None
        orden = OrdenPago.objects.get(numero=request.GET.get('n'))
        try:
            nota=NotaCredito.objects.get(orden=orden)
        except:
            pass
        contexto = {
            'ultimo_dia': datetime.datetime(
                day=calendar.monthrange(orden.fecha.date().year, orden.fecha.date().month)[1],
                month=orden.fecha.date().month, year=orden.fecha.date().year, hour=16, minute=30, second=0),
            'orden': orden,
            'consultas': Extenos.objects.all(),
            'documentos': TipoDocumento.objects.all(),
            'nota_credito':nota,
        }
        return render_to_pdf(template_src='facturacion/reporte.html', context_dict=contexto)
    if request.POST:
        cliente = None
        try:
            cliente = Clientes.objects.create(
                identificacion=request.POST.get('identificacion'),
                numero_identificacion=request.POST.get('cedula'),
                razon_social=request.POST.get("nombres").replace("',)","").replace("('","") + " " + request.POST.get("apellidos").replace("',)","").replace("('",""),
                direccion=request.POST.get('direccion'),
                telefono=request.POST.get('telefono'),
                email=request.POST.get('email')
            )
        except:
            cliente = Clientes.objects.get(numero_identificacion=request.POST.get('cedula'))
            cliente.numero_identificacion = request.POST.get('cedula')
            cliente.identificacion = request.POST.get('identificacion')
            cliente.direccion = request.POST.get('direccion')
            cliente.telefono = request.POST.get('telefono')
            cliente.razon_social = request.POST.get("nombres")+ " " + request.POST.get("apellidos")
            cliente.email = request.POST.get('email')
            cliente.save()
        orden = OrdenPago.objects.create(
            placa=request.POST.get("placa"),
            avaluo=request.POST.get("avaluo"),
            tonelaje=request.POST.get("tonelaje"),
            cedula=request.POST.get("cedula"),
            nombres=request.POST.get("nombres"),
            apellidos=request.POST.get("apellidos"),
            total=request.POST.get("total"),
            cliente=cliente
        )
        detallenotas = json.loads(request.POST.get('detallenota'))
        print(request.POST.get("ndate"))

        if request.POST.get("nn"):
            nota=NotaCredito.objects.create(
                fecha=request.POST.get("ndate"),
                numero=request.POST.get('nn'),
                cliente=cliente,
                valor=request.POST.get("nvl"),
                orden=orden,
            )
        detalles = json.loads(request.POST.get('detalles'))

        contador = 0
        for det in detalles:
            contador = contador + 1
            ndet = DetalleOrden.objects.filter(electronico=True).count()
            dt = DetalleOrden.objects.create(
                orden=orden,
                items_id=det['id'],
                cantidad=det['cantidad'],
                costo=det['precio'],
                total=det['total'],
                electronico=True,
                n_comprobante="",
            )
            print(det['id'], det['cantidad'], det['precio'], det['total'])
        orden.numero_items = contador
        orden.save()
        if request.POST.get("nn"):
            for dnota in detallenotas:
                detn=DetalleNotaCredito.objects.create(
                    codigo=dnota['codigo'],
                    nota = nota,
                    cantidad = 1,
                    descripcion = dnota['detalle'],
                    valor = dnota['valor'],
                )
        print(cliente)
        print(orden)
        return HttpResponse(orden.numero)
    else:
        return HttpResponse("Registro de ordenes de pago")


def autorizar_facturas(request):
    f1 = f2 = None
    # for i in DetalleOrden.objects.filter(orden__fecha='2024-07-01'):
    #     i.electronico=True
    #     i.save()
    # for i in DetalleOrden.objects.all():
    #     i.electronico=False
    #     i.save()
    if request.GET.get('f1'):
        f1 = str(request.GET.get('f1'))
        f1 = datetime.datetime.strptime(f1, "%Y-%m-%d")

    else:
        f1 = datetime.datetime.now().date()
    if request.GET.get('f2'):
        f2 = str(request.GET.get('f2'))
        f2 = datetime.datetime.strptime(f2, "%Y-%m-%d")

    else:
        f2 = datetime.datetime.now().date()

    detalles = DetalleOrden.objects.filter(orden__eliminar=False, orden__estado=True,
                                           orden__fecha__range=[f1, f2]).exclude(
        items__descripcion='Servicios administrativos')
    if request.GET.get('n'):
        dt = DetalleOrden.objects.get(id=request.GET.get('n'))
        cont = generar_xml(dt.orden, dt)
        messages.add_message(request, messages.SUCCESS,
                             'El registro se envió, esperando la respuesta por parte del SRI ' + str(cont))
    contexto = {
        'detalles': detalles,
        'f1': f1,
        'f2': f2
    }
    if request.GET.get('ride'):
        contexto = {
            'configuracion': Configuracion.objects.get(estado=True),
            'detalle': DetalleOrden.objects.get(id=request.GET.get('ride')),
        }
        return render_to_pdf('facturacion/ride.html', contexto)
    return render(request, 'facturacion/listado_facturacion_electronica.html', contexto)


def lista_ordenes(request):
    if request.POST:
        fp = False
        print(request.POST.get('fp'))
        if request.POST.get('fp')=='on':
            fp = True
        orden = OrdenPago.objects.get(id=request.POST.get('id'))
        orden.estado = True
        orden.fecha = request.POST.get('fecha')
        orden.pago_electronico = fp
        orden.save()
        messages.add_message(request, messages.SUCCESS, "Se ha verificado el pago ..!")
    if request.GET.get('del'):
        orden = OrdenPago.objects.get(id=request.GET.get('del'))
        orden.estado = False
        orden.eliminar = True
        orden.save()
        messages.add_message(request, messages.ERROR, "La Orden se elimino..!")
        return HttpResponseRedirect("/fact/lista")
    contexto = {
        'ordenes': OrdenPago.objects.all().order_by('-fecha')[0:2000],
        'consultas': Extenos.objects.all(),
        'documentos': TipoDocumento.objects.all(),
    }
    return render(request, 'facturacion/lista.html', contexto)


def reporte_facturacion(request):
    formato = '%Y-%m-%d'
    if request.GET.get('f1'):
        f1 = datetime.datetime.strptime(request.GET.get('f1'), formato)
        f1 = datetime.datetime(year=f1.year, month=f1.month, day=f1.day, hour=0, minute=0)
    else:
        f1 = datetime.datetime.now()
        f1 = datetime.datetime(year=f1.year, month=f1.month, day=f1.day, hour=0, minute=0)
    if request.GET.get('f2'):
        f2 = datetime.datetime.strptime(request.GET.get('f2'), formato)
        f2 = datetime.datetime(year=f2.year, month=f2.month, day=f2.day, hour=23, minute=59)
    else:
        f2 = datetime.datetime(year=datetime.datetime.now().year, month=datetime.datetime.now().month,
                               day=calendar.monthrange(datetime.datetime.now().year, datetime.datetime.now().month)[
                                   1]).date()
        f2 = datetime.datetime(year=f2.year, month=f2.month, day=f2.day, hour=23, minute=59)
    ordenes = OrdenPago.objects.filter(fecha__range=[f1, f2])
    anuladas = ordenes
    pagos=DetalleOrden.objects.filter(orden__fecha__range=[f1, f2], orden__estado=True)
    pagos_e=pagos.filter(orden__pago_electronico=False)
    pagos_elec=pagos.filter(orden__pago_electronico=True)
    efectivo=pagos_e.values('items__codigo').annotate(Sum('total'))
    total_efectivo=pagos_e.aggregate(Sum('total'))
    electronico = pagos_elec.values('items__codigo').annotate(Sum('total'))
    total_electronico = pagos_elec.aggregate(Sum('total'))
    notas_credito=DetalleNotaCredito.objects.filter(nota__orden__fecha__range=[f1, f2])
    total_notas_credito=notas_credito.values('valor').aggregate(valor=Sum('valor'))

    contexto = {
        'consultas': Extenos.objects.all(),
        'documentos': TipoDocumento.objects.all(),
        'ordenes': ordenes,
        'nordenes': ordenes.count(),
        'anuladas': anuladas.count(),
        'total_anuladas': anuladas.aggregate(total=Sum('total')),
        'f1': f1,
        'f2': f2,
        'total_general': ordenes.exclude(eliminar=True).aggregate(total=Sum('total')),
        'total_verificado': ordenes.filter(estado=True).exclude(eliminar=True).aggregate(total=Sum('total')),
        'total_rubros': DetalleOrden.objects.filter(orden__fecha__range=[f1, f2], orden__estado=True)
        .values('items__codigo', 'items__descripcion', 'items__avaluo__desde', 'items__avaluo__hasta',
                'items__tonelaje__desde',
                'items__tonelaje__hasta')
        .order_by('items_id')
        .annotate(total_rubros=Sum('total')),
        'total_rubros_notas_credito': notas_credito.values('codigo','descripcion').annotate(valor=Sum('valor')),
        'agrupados': DetalleOrden.objects.filter(orden__fecha__range=[f1, f2], orden__estado=True).values(
            'items__codigo').annotate(
            Sum('total')
        ),
        'efectivo':efectivo,
        'total_efectivo':total_efectivo,
        'electronico': electronico,
        'total_electronico': total_electronico,
        'fecha': datetime.datetime.now(),
        'usuario': request.user.get_full_name(),
        'total_notas_credito': float(total_notas_credito.get('valor')) if total_notas_credito.get('valor') else 0.00,
    }
    if request.GET.get('imp'):
        return render_to_pdf('facturacion/resumen.html', contexto)
    else:
        return render(request, 'facturacion/reporte_recaudacion.html', contexto)
