from django.shortcuts import render
from django.shortcuts import render
from django.views.decorators.cache import never_cache
from django.utils.decorators import method_decorator
from django.views import generic
from django.db.models import Q
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from django.urls import reverse_lazy
from django.contrib.auth.mixins import PermissionRequiredMixin,LoginRequiredMixin
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.http import HttpResponseRedirect
from django import forms
from django.http import HttpResponse
from .models import Estudiante, Matricula,Calificacion,PeriodoAcademico,Materia
from django.shortcuts import render,  get_object_or_404

def index(request):
  
    asignaciones_caso = "hola"
    return render(
        request,
        'index.html',
        context={'cantidadCliente': {asignaciones_caso}}
    )


@never_cache
@login_required
def mis_materias(request):
    estudiante = request.user.estudiante  # Obtiene el estudiante autenticado

    # Obtener el período seleccionado desde el GET o el más reciente activo
    periodo_id = request.GET.get('periodo')
    if periodo_id:
        periodo_seleccionado = PeriodoAcademico.objects.get(id=periodo_id)
    else:
        periodo_seleccionado = PeriodoAcademico.objects.filter(activo=True).first()

    # Obtener las materias en las que el estudiante está matriculado en ese período
    materias_matriculadas = Matricula.objects.filter(estudiante=estudiante, periodo=periodo_seleccionado)

    # Obtener las calificaciones relacionadas con las matrículas
    calificaciones = {c.matricula.id: c for c in Calificacion.objects.filter(matricula__in=materias_matriculadas)}

    return render(request, 'mis_materias.html', {
        'materias_matriculadas': materias_matriculadas,
        'calificaciones': calificaciones,
        'periodos': PeriodoAcademico.objects.all(),
        'periodo_seleccionado': periodo_seleccionado,
    })


from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import PeriodoAcademico, Materia, Matricula, Calificacion

@login_required
def calificaciones_docente(request):
    try:
        docente = request.user.docente  
    except AttributeError:
        return render(request, "error.html", {"mensaje": "No tienes permisos para acceder a esta página."})

    periodos = PeriodoAcademico.objects.all()
    periodo_seleccionado = None
    materias_asignadas = []
    estudiantes_matriculados = []
    calificaciones_dict = {}
    materia_seleccionada = None

    periodo_id = request.GET.get("periodo")
    materia_id = request.GET.get("materia")

    if periodo_id:
        periodo_seleccionado = get_object_or_404(PeriodoAcademico, id=periodo_id)
        materias_asignadas = Materia.objects.filter(docente=docente, nivel__periodo=periodo_seleccionado)

        if materia_id:
            materia_seleccionada = get_object_or_404(Materia, id=materia_id, docente=docente)
            estudiantes_matriculados = Matricula.objects.filter(
                materia=materia_seleccionada, periodo=periodo_seleccionado
            ).select_related("estudiante")

            # Obtener todas las calificaciones de los estudiantes matriculados
            calificaciones = {c.matricula.id: c for c in Calificacion.objects.filter(matricula__in=estudiantes_matriculados)}

            # Asegurar que cada estudiante tenga una calificación en el diccionario
            for matricula in estudiantes_matriculados:
                if matricula.id not in calificaciones:
                    calificaciones[matricula.id] = None  # No existe aún

            calificaciones_dict = calificaciones

    # Lista de campos de calificaciones
    campos_notas = [
        "nota1_sem1", "nota2_sem1", "prueba_sem1", "examen_sem1",
        "nota1_sem2", "nota2_sem2", "prueba_sem2", "examen_sem2",
        "recuperacion"
    ]

    return render(
        request,
        "calificaciones_docente.html",
        {
            "periodos": periodos,
            "periodo_seleccionado": periodo_seleccionado,
            "materias_asignadas": materias_asignadas,
            "materia_seleccionada": materia_seleccionada,
            "estudiantes_matriculados": estudiantes_matriculados,
            "calificaciones": calificaciones_dict,
            "campos_notas": campos_notas,  # 👈 PASAMOS LA LISTA A LA PLANTILLA
        },
    )



from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import Calificacion, Matricula

@csrf_exempt
def guardar_calificacion(request):
    """ Guarda automáticamente la calificación cuando el usuario edita un campo """
    if request.method == "POST":
        matricula_id = request.POST.get("matricula_id")
        campo = request.POST.get("campo")
        valor = request.POST.get("valor")

        try:
            # Obtener o crear la calificación
            calificacion, created = Calificacion.objects.get_or_create(matricula_id=matricula_id)

            # Convertir el valor a decimal y asignarlo al campo correspondiente
            setattr(calificacion, campo, float(valor) if valor else None)
            
            # Guardar en la base de datos
            calificacion.save()

            return JsonResponse({"success": True, "message": "Calificación guardada correctamente."})
        except Calificacion.DoesNotExist:
            return JsonResponse({"error": "Calificación no encontrada"}, status=404)
        except Exception as e:
            return JsonResponse({"error": str(e)}, status=500)

    return JsonResponse({"error": "Método no permitido"}, status=405)

from django.http import HttpResponse
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    PageBreak, KeepTogether
)
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import inch
from django.shortcuts import get_object_or_404
from .models import Materia, PeriodoAcademico, Matricula, Calificacion

def generar_acta_notas(request):
    materia_id = request.POST.get("materia") or request.GET.get("materia")
    periodo_id = request.POST.get("periodo") or request.GET.get("periodo")

    if not materia_id or not periodo_id:
        return HttpResponse("Faltan parámetros requeridos", status=400)

    materia = get_object_or_404(Materia, id=materia_id)
    periodo = get_object_or_404(PeriodoAcademico, id=periodo_id)
    matriculas = Matricula.objects.filter(materia=materia, periodo=periodo)
    nivel = materia.nivel

    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="acta_notas.pdf"'

    doc = SimpleDocTemplate(response, pagesize=letter,
                            leftMargin=50, rightMargin=50, topMargin=60, bottomMargin=60)

    styles = getSampleStyleSheet()
    elements = []

    # Encabezado
    elements.append(Paragraph("<b>Instituto Superior Tecnológico de la Vera Cruz</b>", styles['Title']))
    elements.append(Paragraph("Av. La Gasca Oe6-29 y Francisco Viteri", styles['Normal']))
    elements.append(Paragraph("<b>ACTA DE CALIFICACIONES</b>", styles['Heading2']))
    elements.append(Spacer(1, 20))

    # Información General
    def bold_label(label, value):
        return Paragraph(f'<b>{label}</b> {value}', styles['Normal'])

    docente_text = str(materia.docente) if materia.docente else "N/A"
    elements.extend([
        Paragraph('<b>Información General</b>', styles['Heading4']),
        Spacer(1, 6),
        bold_label("Periodo:", str(periodo.nombre)),
        bold_label("Carrera:", str(materia.nivel.programa.nombre)),
        bold_label("Materia:", str(materia.nombre)),
        bold_label("Docente:", docente_text),
        bold_label("Nivel:", str(nivel.nivel)),
        bold_label("Modalidad:", str(nivel.programa.modalidad)),
        Spacer(1, 20)
    ])

    # Tabla de calificaciones
    data = [
        ["", "", "", "", "", "", "", ""],
        ["Cédula", "Estudiante", "Promedio 1", "Promedio 2", "Recuperación", "Asistencia", "Nota Final", "Estado"]
    ]

    for matricula in matriculas:
        calificacion = Calificacion.objects.filter(matricula=matricula).first()
        if calificacion:
            promedio1 = calificacion.promedio1()
            promedio2 = calificacion.promedio2()
            nota_final = calificacion.nota_final()
            estado = "Aprobado" if nota_final and nota_final >= 7 else "Reprobado"
            data.append([
                matricula.estudiante.nui,
                f"{matricula.estudiante.apellido}, {matricula.estudiante.nombre}",
                promedio1 or 0.0,
                promedio2 or 0.0,
                calificacion.recuperacion or 0.0,
                calificacion.asistencia or 0.0,
                round(nota_final, 2) if nota_final is not None else 0.0,
                estado
            ])
        else:
            data.append([
                matricula.estudiante.nui,
                f"{matricula.estudiante.apellido}, {matricula.estudiante.nombre}",
                "-", "-", "-", "-", "-", "-"
            ])

    col_widths = [50, 180, 58, 58, 65, 55, 50, 50]
    table = Table(data, colWidths=col_widths, repeatRows=2)
    table.setStyle(TableStyle([
        ("SPAN", (2, 0), (3, 0)),
        ("SPAN", (4, 0), (7, 0)),
        ("ALIGN", (0, 0), (-1, -1), "LEFT"),
        ("ALIGN", (2, 0), (3, 0), "CENTER"),
        ("ALIGN", (4, 0), (7, 0), "CENTER"),
        ("BACKGROUND", (0, 0), (-1, 0), colors.white),
        ("TEXTCOLOR", (0, 0), (-1, 0), colors.black),
        ("BACKGROUND", (0, 1), (-1, 1), colors.HexColor("#0B0E32")),
        ("TEXTCOLOR", (0, 1), (-1, 1), colors.white),
        ("FONTNAME", (0, 0), (-1, 1), "Helvetica-Bold"),
        ("FONTNAME", (0, 2), (-1, -1), "Helvetica"),
        ("FONTSIZE", (0, 0), (-1, 1), 6),
        ("FONTSIZE", (0, 2), (-1, -1), 6),

        ("GRID", (0, 0), (-1, -1), 0.5, colors.whitesmoke),
    ]))

    elements.append(table)
    elements.append(Spacer(1, 30))

            # Firmas en formato de tabla: Vicerrectorado a la izquierda, Docente al centro
      # Firmas en formato de tabla: Docente a la izquierda, Vicerrectorado a la derecha
    firmas_data = [
        [
            Paragraph("______________________________", styles['Normal']),
            Paragraph("___________________", styles['Normal'])
        ],
        [
            Paragraph(docente_text, styles['Normal']),
            Paragraph("Vicerrectorado Académico", styles['Normal'])
        ],
        [
            Paragraph("Docente", styles['Normal']),
            ""
        ]
    ]
    
    firmas_table = Table(firmas_data, colWidths=[250, 250])
    firmas_table.setStyle(TableStyle([
        ('ALIGN', (0, 0), (0, -1), 'LEFT'),    # Docente alineado a la izquierda
        ('ALIGN', (1, 0), (1, -1), 'CENTER'),  # Vicerrectorado alineado al centro
        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
        ('TOPPADDING', (0, 0), (-1, -1), 6),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 6),
    ]))
    
    elements.append(Spacer(1, 40))
    elements.append(firmas_table)




    doc.build(elements)
    return response









































@method_decorator(never_cache, name='dispatch') 
class estudianteListView(generic.ListView):
   model = Estudiante
   permission_required = 'informacion.add_estudiante'

   paginate_by = 20

   def get_queryset(self):
        query = self.request.GET.get('q')
        queryset = super().get_queryset()

        if query:
            queryset = queryset.filter(Q(nui__icontains=query) | Q(apellido__icontains=query)| Q(nombre__icontains=query))

        return queryset

@method_decorator(login_required, name='dispatch')
@method_decorator(never_cache, name='dispatch') 
class estudianteCreate(PermissionRequiredMixin,CreateView):
    model = Estudiante
    fields = ['nui', 'apellido','nombre']
    permission_required = 'model.add_estudiante'
    def form_valid(self, form):
        return super().form_valid(form)

    def get_success_url(self):
        return reverse_lazy('estudiante-detail', kwargs={'pk': self.object.pk})   


@method_decorator(login_required, name='dispatch')
@method_decorator(never_cache, name='dispatch') 
class estudianteDetailView(generic.DetailView):
    model = Estudiante
    context_object_name = 'estudiante'
    template_name = 'informacion/estudiante.html'  

   

@method_decorator(login_required, name='dispatch')
@method_decorator(never_cache, name='dispatch') 
class estudianteUpdate(LoginRequiredMixin, UpdateView):
    model = Estudiante
    fields = ['nui', 'apellido','nombre']
    def form_valid(self, form):
        return super().form_valid(form)

    def get_success_url(self):
        return reverse_lazy('estudiante-update', kwargs={'pk': self.object.pk})

@method_decorator(login_required, name='dispatch')
@method_decorator(never_cache, name='dispatch') 
class estudianteDelete(LoginRequiredMixin, DeleteView):
    model = Estudiante
    success_url = reverse_lazy('estudiante')
    permission_required = 'informacion.delete_estudiante'

    def form_valid(self, form):
        try:
            self.object.delete()
            return HttpResponseRedirect(self.success_url)
        except Exception as e:
            pass








@login_required
def estudiante_periodos(request, pk):
    estudiante = get_object_or_404(Estudiante, pk=pk)
    
    # Obtener todos los periodos en los que el estudiante tiene matrículas activas
    periodos = PeriodoAcademico.objects.filter(
        matricula__estudiante=estudiante
    ).distinct()

    return render(request, 'informacion/estudiante_periodos.html', {
        'estudiante': estudiante,
        'periodos': periodos
    })
    
    
# views.py
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.contrib.auth.decorators import login_required
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet
from .models import Estudiante, Matricula, Calificacion
from reportlab.lib.units import inch
from reportlab.lib.styles import ParagraphStyle
from reportlab.platypus import Spacer
from django.conf import settings
import os
from reportlab.platypus import Image

@login_required
def generar_pdf_periodo(request, estudiante_id, periodo_id):
    estudiante = get_object_or_404(Estudiante, pk=estudiante_id)
    periodo = get_object_or_404(PeriodoAcademico, pk=periodo_id)
    matriculas = Matricula.objects.filter(estudiante=estudiante, periodo=periodo)

    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = f'attachment; filename="Calificaciones_{estudiante.nui}.pdf"'

    doc = SimpleDocTemplate(
        response, pagesize=letter,
        leftMargin=50, rightMargin=50,
        topMargin=60, bottomMargin=60
    )
    styles = getSampleStyleSheet()
    elements = []
    logo_path = os.path.join(settings.BASE_DIR, "static", "img", "logo_instituto.png")
    logo = Image(logo_path, width=140, height=35)
    logo.hAlign = "CENTER"
    elements.append(logo)
    elements.append(Spacer(1, 12))






    # Encabezado
    elements.append(Paragraph("<b>Instituto Superior Tecnológico de la Vera Cruz</b>", styles['Title']))
    elements.append(Spacer(1, 12))
    elements.append(Paragraph("<b>Hoja de Calificaciones</b>", styles['Heading2']))
    elements.append(Spacer(1, 20))

    # Diccionario de semestres
    SEMESTRES = {
        1: "PRIMER ",
        2: "SEGUNDO ",
        3: "TERCERO ",
        4: "CUARTO ",
        5: "QUINTO ",
        6: "SEXTO ",
    }

    # Info del estudiante
    info_data = [
        ["Periodo Académico:", periodo.nombre],
        ["Estudiante:", f"{estudiante.nombre} {estudiante.apellido}"],
        ["Cédula:", estudiante.usuario.username],
    ]

    if matriculas.exists():
        nivel = matriculas.first().materia.nivel
        programa = nivel.programa
        semestre_texto = SEMESTRES.get(nivel.nivel, f"Nivel {nivel.nivel}")
        info_data += [
            ["Nivel:", semestre_texto],
            ["Modalidad:", programa.modalidad],
            ["Carrera:", programa.nombre],
        ]
    else:
        info_data += [
            ["Nivel:", "-"],
            ["Modalidad:", "-"],
            ["Carrera:", "-"],
        ]

    info_table = Table(info_data, colWidths=[120, 300], hAlign="LEFT")
    info_table.setStyle(TableStyle([
        ("GRID", (0,0), (-1,-1), 0, colors.white),
        ("ALIGN", (0,0), (-1,-1), "LEFT"),
        ("FONTNAME", (0,0), (-1,-1), "Helvetica"),
        ("FONTSIZE", (0,0), (-1,-1), 10),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ]))
    elements.append(info_table)
    elements.append(Spacer(1, 12))

    # Tabla de materias y calificaciones
    data = [["ID", "Materia", "1er HEMI", "2do HEMI", "Recup.", "Nota Final", "Asistencia", "Estado"]]

    total_notas = 0
    contador_materias = 0

    for matricula in matriculas:
        calificacion = Calificacion.objects.filter(matricula=matricula).first()
        if calificacion:
            promedio_final = calificacion.nota_final() or 0.0
            estado = "Aprobado" if promedio_final >= 7 else "Reprobado"
            data.append([
                matricula.id,
                matricula.materia.nombre,
                calificacion.promedio1() or 0.0,
                calificacion.promedio2() or 0.0,
                calificacion.recuperacion or 0.0,
                round(promedio_final, 2),
                f"{calificacion.asistencia or 0}%",
                estado
            ])

            # Sumatoria para el record académico
            total_notas += promedio_final
            contador_materias += 1
        else:
            data.append([matricula.id, matricula.materia.nombre, "-", "-", "-", "-", "-", "-"])

    col_widths = [30, 180, 50, 50, 50, 50, 50, 50]
    table = Table(data, colWidths=col_widths, repeatRows=1)
    table.setStyle(TableStyle([
        ("GRID", (0,0), (-1,-1), 0.5, colors.black),
        ("BACKGROUND", (0,0), (-1,0), colors.HexColor("#0B0E32")),
        ("TEXTCOLOR", (0,0), (-1,0), colors.white),
        ("ALIGN", (0,0), (-1,-1), "LEFT"),
        ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTNAME", (0,1), (-1,-1), "Helvetica"),
        ("FONTSIZE", (0,0), (-1,-1), 8),
    ]))
    elements.append(table)

    elements.append(Spacer(1, 20))

    # === Nueva tabla: Record Académico ===
    record_academico = round(total_notas / contador_materias, 2) if contador_materias > 0 else 0.0
    record_table = Table(
        [["Record Académico:", record_academico]],
        colWidths=[150, 100],
        hAlign="LEFT"
    )
    record_table.setStyle(TableStyle([
        ("GRID", (0,0), (-1,-1), 0.5, colors.black),
        ("BACKGROUND", (0,0), (0,0), colors.HexColor("#F2F2F2")),
        ("FONTNAME", (0,0), (-1,-1), "Helvetica-Bold"),
        ("FONTSIZE", (0,0), (-1,-1), 10),
        ("ALIGN", (0,0), (-1,-1), "LEFT"),
    ]))
    elements.append(record_table)

    elements.append(Spacer(1, 100))

    # Firmas
    firma_style = ParagraphStyle(
        name="FirmaStyle",
        parent=styles["Normal"],
        alignment=1,
        leading=12,
        fontSize=10
    )

    firmas_data = [
        [Paragraph("________________________________", firma_style)],
        [Paragraph("MBA. Alexandra del Roció Garzón Rengifo", firma_style)],
        [Paragraph("Vicerrectorado Académico", firma_style)]
    ]

    firmas_table = Table(firmas_data, colWidths=[250], hAlign="CENTER")
    firmas_table.setStyle(TableStyle([
        ('ALIGN', (0,0), (-1,-1), 'CENTER'),
        ('TOPPADDING', (0,0), (-1,-1), 2),
        ('BOTTOMPADDING', (0,0), (-1,-1), 2),
    ]))
    elements.append(firmas_table)

    doc.build(elements)
    return response
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

