import os
from django.conf import settings
from django.template import Context
from django.template.loader import get_template
from xhtml2pdf import pisa
from django.contrib.staticfiles import finders
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.http.response import HttpResponse
from django.views import View
from django.views.generic import ListView
from datetime import datetime
from .models import ordenservicio, serviciorealizado, accesorios, tiposervicio, falla, refacciones, preventivo
from .forms import Formpreventivo, FormpreventivoEnv, Formordenservicio, FormordenservicioEnv, Formserviciorealizado, FormserviciorealizadoEnv, Formaccesorios, FormaccesoriosEnv, FormordenservicioEnvbit, FormordenservicioEnvbit1, FormordenservicioEnvbit2, FormordenservicioEnvbit3, FormordenservicioEnvbit4, FormordenservicioEnvbit5, FormordenservicioEnvbit6, Formrefacciones
from servicios.models import serviciorealizado, accesorios
from inventario.models import invequipo
from pendientes.models import bitpendientes
from bitacora.models import bitreporte
from inventarioalmacen.models import pieza
from openpyxl import Workbook
import datetime
from datetime import date



# Create your views here.
def servicios(request):
    datos = ordenservicio.objects.all()
    equipo = invequipo.objects.all()
    servicios = serviciorealizado.objects.all()
    usuarios = User.objects.all()
    accesorio = accesorios.objects.all()
    return render(request, 'servicios.html', {"datos": datos, "servicios": servicios, "equipo": equipo, "usuarios": usuarios, "accesorio": accesorio})


@login_required(login_url='/acceder')
def crear_ordservicio(request):
    if request.method == "POST":
        form = Formordenservicio(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            folio = form.cleaned_data.get("folio")
            n_control = form.cleaned_data.get("orden_n_control")
            messages.success(request, f"La servicio con el {folio} se ha creado o actualizado correctamente")
            form = FormserviciorealizadoEnv()
            return render(request, "crear_servrealizado.html", {"form": form, "folio": folio, "n_control": n_control})
        else:
            for field, items in form.errors.items():
                for item in items:
                    messages.error(request, '{}: {}'.format(field, item))
    scan = ordenservicio.objects.latest('id')
    date = datetime.datetime.now()
    folio = scan.folio + 1
    hora = date.strftime("%H:%M:%S")
    form = FormordenservicioEnv()
    return render(request, "crear_servicio.html", {"form": form, "folio": folio, "hora": hora})


@login_required(login_url='/acceder')
def crear_ordserviciobit(request, cb):
    if request.method == "POST":
        form = Formordenservicio(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            folio = form.cleaned_data.get("folio")
            nreporte = form.cleaned_data.get("n_reporte")
            update = bitreporte.objects.values('pendiente').filter(control_bit=nreporte).update(pendiente='Realizado')
            update1 = bitpendientes.objects.values('concluido').filter(n_reporte=nreporte).update(concluido='Realizado')
            messages.success(request, f"La servicio con el {folio} se ha creado o actualizado correctamente")
            return redirect("servicios")
        else:
            for field, items in form.errors.items():
                for item in items:
                    messages.error(request, '{}: {}'.format(field, item))
    scan = ordenservicio.objects.latest('id')
    date = datetime.datetime.now()
    folio = scan.folio + 1
    hora = date.strftime("%H:%M:%S")
    controlb = cb
    dato = bitreporte.objects.filter(control_bit=controlb)
    falla = dato[0].reporte
    reporta_ib = dato[0].asignado.id
    quien_reporta = dato[0].quien_reporta
    reporta_ib_1 = dato[0].asignado
    if bitpendientes.objects.filter(n_reporte=cb).exists():
        datos = bitpendientes.objects.get(n_reporte=cb)
        form1 = FormordenservicioEnvbit1()
        form2 = FormordenservicioEnvbit2()
        form3 = FormordenservicioEnvbit3()
        form4 = FormordenservicioEnvbit4()
        form5 = FormordenservicioEnvbit5()
        form6 = FormordenservicioEnvbit6()
        datosseg = serviciorealizado.objects.filter(control_bit=cb)
        datosacc = accesorios.objects.filter(control_bit=cb)
        return render(request, "crear_serviciobit.html", {"form1": form1, "form2": form2, "form3": form3, "form4": form4, "form5": form5, "form6": form6, "folio": folio, "hora": hora, "controlb": controlb, "datos": datos, "falla": falla, "reporta_ib": reporta_ib, "reporta_ib_1": reporta_ib_1, "quien_reporta": quien_reporta, "datosseg": datosseg, "datosacc": datosacc})
    else:    
        form1 = FormordenservicioEnvbit1()
        form2 = FormordenservicioEnvbit2()
        form3 = FormordenservicioEnvbit3()
        form4 = FormordenservicioEnvbit4()
        form5 = FormordenservicioEnvbit5()
        form6 = FormordenservicioEnvbit6()
        datosseg = serviciorealizado.objects.filter(control_bit=cb)
        datosacc = accesorios.objects.filter(control_bit=cb)
        return render(request, "crear_serviciobit.html", {"form1": form1, "form2": form2, "form3": form3, "form4": form4, "form5": form5, "form6": form6, "folio": folio, "hora": hora, "controlb": controlb, "falla": falla, "reporta_ib": reporta_ib, "reporta_ib_1": reporta_ib_1, "quien_reporta": quien_reporta, "datosseg": datosseg, "datosacc": datosacc})
        pass

@login_required(login_url='/acceder')
def ActualizarOrden(request, id):
        instance= get_object_or_404(ordenservicio, pk=id)
        form = Formordenservicio(request.POST or None, instance=instance)
        context= {'form': form}
        if form.is_valid():
                obj= form.save(commit= False)
                obj.save()
                messages.success(request, "La Orden fue actualizada")
                return redirect("servicios")

        else:
                context= {'form': form, 'error': 'Error al actualizar'}
                return render(request,'actualizar_orden.html' , context)




################################ servicios realizados ###################################

@login_required(login_url='/acceder')
def crear_servrealizado(request):
    if request.method == "POST":
        form = Formserviciorealizado(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            folio = form.cleaned_data.get("folio")
            control_bit = form.cleaned_data.get("control_bit")
            n_control = form.cleaned_data.get("ser_s_n_control")
            messages.success(request, f"El servicio con el reporte: {control_bit} se ha creado o actualizado correctamente")
            form = FormaccesoriosEnv()
            return render(request, "crear_servaccesorios.html", {"form": form, "folio": folio, "control": control_bit, "n_control": n_control})
        else:
            for field, items in form.errors.items():
                for item in items:
                    messages.error(request, '{}: {}'.format(field, item))

    form = FormserviciorealizadoEnv()
    datos = serviciorealizado.objects.all()
    return render(request, "crear_servrealizado.html", {"form": form, "datos": datos})



@login_required(login_url='/acceder')
def crear_servrealizadopen(request, cb):
    if request.method == "POST":
        form = Formserviciorealizado(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            folio = form.cleaned_data.get("control_bit")
            messages.success(request, f"El servicio con el reporte: {folio} se ha creado o actualizado correctamente")
            return redirect("index")
        else:
            for field, items in form.errors.items():
                for item in items:
                    messages.error(request, '{}: {}'.format(field, item))

    form = FormserviciorealizadoEnv()
    controlcb = cb
    datos = bitpendientes.objects.get(n_reporte=cb)
    datosseg = serviciorealizado.objects.filter(control_bit=cb)
    return render(request, "penseguimiento.html", {"form": form, "controlcb": controlcb, "datos": datos, "datosseg": datosseg})


@login_required(login_url='/acceder')
def crear_servrealizadobit(request, cb):
    if request.method == "POST":
        form = Formserviciorealizado(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            reporte1 = form.cleaned_data.get("control_bit")
            messages.success(request, f"El seguimiento con el reporte: {reporte1} se ha creado o actualizado correctamente")
            return redirect("bitacora")
        else:
            for field, items in form.errors.items():
                for item in items:
                    messages.error(request, '{}: {}'.format(field, item))

    form = FormserviciorealizadoEnv()
    controlcb = cb
    datos = bitreporte.objects.get(control_bit=cb)
    datosseg = serviciorealizado.objects.filter(control_bit=cb)
    return render(request, "bitseguimiento.html", {"form": form, "controlcb": controlcb, "datos": datos, "datosseg": datosseg})



@login_required(login_url='/acceder')
def crear_servrealizadocon(request, cb):
    if request.method == "POST":
        form = Formserviciorealizado(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            reporte1 = form.cleaned_data.get("control_bit")
            messages.success(request, f"El seguimiento con el reporte: {reporte1} se ha creado o actualizado correctamente")
            return redirect("bitacora")
        else:
            for field, items in form.errors.items():
                for item in items:
                    messages.error(request, '{}: {}'.format(field, item))

    form = FormserviciorealizadoEnv()
    controlcb = cb
    datos = ordenservicio.objects.get(n_reporte=cb)
    return render(request, "conseguimiento.html", {"form": form, "controlcb": controlcb, "datos": datos})



@login_required(login_url='/acceder')
def servrealizado(request, cb):
    datos = serviciorealizado.objects.filter(control_bit=cb)
    return render(request, "crear_servrealizado.html", {"datos": datos})


@login_required(login_url='/acceder')
def verservrealizado(request, cb):
    datos = serviciorealizado.objects.filter(control_bit=cb)
    return render(request, "ver_seguimiento.html", {"datos": datos})

################################ accesorios ###################################################



@login_required(login_url='/acceder')
def crear_accesorios(request):
    if request.method == "POST":
        form = Formaccesorios(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            control_bit = form.cleaned_data.get("control_bit")
            messages.success(request, f"El accesorio con el reporte: {control_bit} se ha creado o actualizado correctamente")
            return redirect("servicios")
        else:
            for field, items in form.errors.items():
                for item in items:
                    messages.error(request, '{}: {}'.format(field, item))

    form = FormaccesoriosEnv()
    datos = accesorios.objects.all()
    return render(request, "crear_servaccesorios.html", {"form": form, "datos": datos})


@login_required(login_url='/acceder')
def crear_accesoriospen(request, cb):
    if request.method == "POST":
        form = Formaccesorios(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            control_bit = form.cleaned_data.get("control_bit")
            messages.success(request, f"El accesorio con el Reporte: {control_bit} se ha creado o actualizado correctamente")
            return redirect("pendientes")
        else:
            for field, items in form.errors.items():
                for item in items:
                    messages.error(request, '{}: {}'.format(field, item))

    form = FormaccesoriosEnv()
    controlcb = cb
    dat = bitpendientes.objects.get(n_reporte=cb)
    return render(request, "crear_servaccesoriospen.html", {"form": form, "controlcb": controlcb, "dat": dat})

@login_required(login_url='/acceder')
def crear_accesoriosbit(request, cb):
    if request.method == "POST":
        form = Formaccesorios(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            control_bit = form.cleaned_data.get("control_bit")
            messages.success(request, f"El accesorio con el Reporte: {control_bit} se ha creado o actualizado correctamente")
            return redirect("pendientes")
        else:
            for field, items in form.errors.items():
                for item in items:
                    messages.error(request, '{}: {}'.format(field, item))

    form = FormaccesoriosEnv()
    controlcb = cb
    dat = bitreporte.objects.get(control_bit=cb)
    return render(request, "crear_servaccesoriospen.html", {"form": form, "controlcb": controlcb, "dat": dat})



@login_required(login_url='/acceder')
def servaccesorios(request, cb):
    datos = accesorios.objects.filter(control_bit=cb)
    return render(request, "crear_servaccesorios.html", {"datos": datos})

########################## refacciones ###########################

@login_required(login_url='/acceder')
def crear_refaccionesbit(request, cr, cb):
    if request.method == "POST":
        form = Formrefacciones(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.usuario = request.user
            post.save()
            control_bit = form.cleaned_data.get("n_reporte")
            refex = form.cleaned_data.get("referencia")
            y = form.cleaned_data.get("cantidad")
            x = pieza.objects.only('referencia').filter(referencia=refex)[0]
            nuevo = x.cantidad - y
            update = pieza.objects.values('cantidad').filter(referencia=refex).update(cantidad=nuevo)
            messages.success(request, f"Se agrego la refaccion al Reporte: {control_bit} correctamente")
            return redirect("bitacora")
        else:
            for field, items in form.errors.items():
                for item in items:
                    messages.error(request, '{}: {}'.format(field, item))

    controlcb = cb
    controlcr = cr
    return render(request, "crear_refaccionesbit.html", {"controlcb": controlcb, "controlcr": controlcr})


@login_required(login_url='/acceder')
def crear_refaccionespen(request, cr, cb):
    if request.method == "POST":
        form = Formrefacciones(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            control_bit = form.cleaned_data.get("n_reporte")
            refex = form.cleaned_data.get("referencia")
            y = form.cleaned_data.get("cantidad")
            x = pieza.objects.only('referencia').filter(referencia=refex)[0]
            nuevo = x.cantidad - y
            update = pieza.objects.values('cantidad').filter(referencia=refex).update(cantidad=nuevo)
            messages.success(request, f"Se agrego la refaccion al Reporte: {control_bit} correctamente")
            return redirect("pendientes")
        else:
            for field, items in form.errors.items():
                for item in items:
                    messages.error(request, '{}: {}'.format(field, item))

    controlcb = cb
    controlcr = cr
    return render(request, "crear_refaccionespen.html", {"controlcb": controlcb, "controlcr": controlcr})


@login_required(login_url='/acceder')
def refaccionespre(request, cb):
    controlcb = cb
    datos = pieza.objects.all()
    return render(request, "crear_refaccionespre.html", {"datos": datos, "controlcb": controlcb})


@login_required(login_url='/acceder')
def refacciones1(request, cb):
    controlcb = cb
    datos = refacciones.objects.filter(n_reporte=controlcb)
    return render(request, "refacciones.html", {"datos": datos})


########################## PDF ###################################

class pdf(View):
    def link_callback(self, uri, rel):
        result = finders.find(uri)
        if result:
                if not isinstance(result, (list, tuple)):
                        result = [result]
                result = list(os.path.realpath(path) for path in result)
                path=result[0]
        else:
                sUrl = settings.STATIC_URL        # Typically /static/
                sRoot = settings.STATIC_ROOT      # Typically /home/userX/project_static/
                mUrl = settings.MEDIA_URL         # Typically /media/
                mRoot = settings.MEDIA_ROOT       # Typically /home/userX/project_static/media/

                if uri.startswith(mUrl):
                        path = os.path.join(mRoot, uri.replace(mUrl, ""))
                elif uri.startswith(sUrl):
                        path = os.path.join(sRoot, uri.replace(sUrl, ""))
                else:
                        return uri

            # make sure that file exists
        if not os.path.isfile(path):
                raise Exception(
                        'media URI must start with %s or %s' % (sUrl, mUrl)
                )
        return path



    def get(self, request, *args, **kwargs):
        try:
            dato = ordenservicio.objects.get(pk=self.kwargs['pk'])
            equipo = invequipo.objects.get(n_control=dato.orden_n_control)
            aces = accesorios.objects.filter(control_bit=dato.n_reporte)
            serv = serviciorealizado.objects.filter(control_bit=dato.n_reporte)
            t_serv = tiposervicio.objects.get(pk=dato.tipo_servicio_id)
            t_falla = falla.objects.get(pk=dato.origen_falla_id)
            firma1 = User.objects.get(pk=dato.ib1_id)
            if dato.id_ib2_id is None :
                template = get_template('pdf.html')
                context = {'dato': dato, 'equipo': equipo, 'aces': aces, 'serv': serv , 't_serv': t_serv , 't_falla': t_falla, 'firma1': firma1 }
                html = template.render(context)
                response = HttpResponse(content_type='application/pdf')
                pisa_status = pisa.CreatePDF(
                    html, dest=response,
                    link_callback=self.link_callback
                    )
                return response

            firma2 = User.objects.get(pk=dato.id_ib2_id)
            template = get_template('pdf.html')
            context = {'dato': dato, 'equipo': equipo, 'aces': aces, 'serv': serv , 't_serv': t_serv , 't_falla': t_falla, 'firma1': firma1, 'firma2': firma2  }
            html = template.render(context)
            response = HttpResponse(content_type='application/pdf')
            pisa_status = pisa.CreatePDF(
                html, dest=response,
                link_callback=self.link_callback
                )
            return response
        except:
            pass
        return redirect("servicios")



########################## PREVENTIVO ###################################



class Calendario(ListView):
    model = preventivo
    template_name = 'preventivo1.html'

    def get_context_data(self, **kwargs):
        context = super(Calendario, self).get_context_data(**kwargs)
        listas = preventivo.objects.all()
        context['listas'] = listas
        return context


@login_required(login_url='/acceder')
def Preventivo(request):
	datos = preventivo.objects.filter(estatus="PENDIENTE")
	return render(request, 'preventivo.html', {"datos": datos})


@login_required(login_url='/acceder')
def PreventivoAll(request):
	datos = preventivo.objects.all()
	return render(request, 'preventivoall.html', {"datos": datos})


@login_required(login_url='/acceder')
def crear_preventivo(request):
    if request.method == "POST":
        form = Formpreventivo(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            control_bit = form.cleaned_data.get("n_control")
            messages.success(request, f"El servicio preventivo con numero de control: {control_bit} se ha creado correctamente")
            return redirect("preventivo")
        else:
            for field, items in form.errors.items():
                for item in items:
                    messages.error(request, '{}: {}'.format(field, item))

    form = FormpreventivoEnv()
    return render(request, "crearpreventivo.html", {"form": form })


@login_required(login_url='/acceder')
def ActualizarPreventivo(request, id):
        instance= get_object_or_404(preventivo, pk=id)
        form = Formpreventivo(request.POST or None, instance=instance)
        context= {'form': form}
        if form.is_valid():
            obj= form.save(commit= False)
            obj.save()
            messages.success(request, "El servicio preventivo fue actualizado")
            return redirect("preventivo")
        else:
            context= {'form': form, 'error': 'Error al actualizar'}
            return render(request,'actualizar_preventivo.html' , context)


###################  EXCEL ####################
@login_required(login_url='/acceder')
def ReporteExcelServicios(request):
    servicios = ordenservicio.objects.all()
    ibs = User.objects.all()
    datostiposervicio = tiposervicio.objects.all()
    datosfalla = falla.objects.all()
    datosservicio = serviciorealizado.objects.all()
    datosaccesorios = accesorios.objects.all()
    fecha = datetime.datetime.now()
    fe = str(fecha)
    wb = Workbook()
    ws = wb.active
    ws['B1'] = 'REPORTE DE SERVICIOS CONCLUIDOS'

    ws.merge_cells('B1:L1')

    ws['B2'] = datetime.datetime.now()
    
    ws.merge_cells('B2:D2')

    ws['B3'] = 'FOLIO'
    ws['C3'] = 'FECHA'
    ws['D3'] = 'REPORTA'
    ws['E3'] = 'IB1'
    ws['F3'] = 'IB2'
    ws['G3'] = 'No. CONTROL'
    ws['H3'] = 'No. REPORTE'
    ws['I3'] = 'T. SERVICIO'
    ws['J3'] = 'ORIGEN FALLA'
    ws['K3'] = 'FALLA DETECTADA'
    ws['L3'] = 'SERVICIOS'
    ws['M3'] = 'ACCESORIOS'
    
    cont = 4

    for servicio in servicios:
        for ib in ibs:
            if servicio.ib1_id == ib.id:
                ibuser = ib.username
        ibuser2 = ""
        if servicio.ib2_id is not None :
            for ib in ibs:
                if servicio.ib2_id == ib.id:
                    ibuser2 = ib.username
        for datotiposervicio in datostiposervicio:
            if servicio.tipo_servicio_id == datotiposervicio.id:
                tiposervicio1 = datotiposervicio.nombre
        for datofalla in datosfalla:
            if servicio.origen_falla_id == datofalla.id:
                falla1 = datofalla.nombre
        
        count = 0
        serreali = ""
        for datoservicio in datosservicio:
            if servicio.n_reporte == datoservicio.control_bit:
                count = count + 1
                realizado = str(count) + " - " + datoservicio.descripcion 
                serreali = serreali + " // " + realizado
        if count == 0 :
            serreali = ""
        count = 0

        count1 = 0
        seracce = ""
        for datoaccesorios in datosaccesorios:
            if servicio.n_reporte == datoaccesorios.control_bit:
                count1 = count1 + 1
                acceso = str(count1) + " - " + datoaccesorios.n_parte + " | " + datoaccesorios.descripcion 
                seracce = seracce + " // " + acceso
        if count1 == 0 :
            seracce = ""
        
        ws.cell(row=cont, column=2).value = servicio.folio
        ws.cell(row=cont, column=3).value = servicio.fecha
        ws.cell(row=cont, column=4).value = servicio.reporta
        ws.cell(row=cont, column=5).value = ibuser
        ws.cell(row=cont, column=6).value = ibuser2
        ws.cell(row=cont, column=7).value = servicio.orden_n_control
        ws.cell(row=cont, column=8).value = servicio.n_reporte
        ws.cell(row=cont, column=9).value = tiposervicio1
        ws.cell(row=cont, column=10).value = falla1
        ws.cell(row=cont, column=11).value = servicio.falla_detectada
        ws.cell(row=cont, column=12).value = serreali
        ws.cell(row=cont, column=13).value = seracce

        cont += 1
        serreali = ""
        seracce = ""

    nombre_archivo = "ReporteServicioConcluidos "+fe+".xlsx"
    response = HttpResponse(content_type="application/ms-excel")
    content = "attachment; filename = {0}".format(nombre_archivo)
    response['Content-Disposition'] = content
    wb.save(response)
    return response

