from django.contrib import admin, messages
from django.http import HttpResponse, HttpResponseForbidden
from django.shortcuts import redirect
from django.template.response import TemplateResponse
from django.urls import path
from django.utils import timezone as dj_timezone

from .models import Student, MadrasahProfile


@admin.register(MadrasahProfile)
class MadrasahProfileAdmin(admin.ModelAdmin):
    list_display = (
        "nama_madrasah",
        "npsn",
        "nsm",
        "kepala_madrasah"
    )

    search_fields = (
        "nama_madrasah",
        "npsn",
        "nsm"
    )

    def has_add_permission(self, request):
        return not MadrasahProfile.objects.exists()
@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
    list_display = ("nisn", "full_name", "kelas", "status", "issued_date")
    search_fields = ("nisn", "full_name")
    change_list_template = "admin/kelulusan/student/change_list.html"

    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            path(
                "download-template/",
                self.admin_site.admin_view(self.download_template),
                name="kelulusan_student_download_template",
            ),
            path(
                "import-excel/",
                self.admin_site.admin_view(self.import_excel),
                name="kelulusan_student_import_excel",
            ),
        ]
        return my_urls + urls

    def _render_change_list_with_message(self, request, **context):
        # Pakai context standar admin agar semua link/template tag yang
        # bergantung ke admin context (mis. app_list) tidak error.
        admin_context = self.admin_site.each_context(request)
        admin_context.update(context)

        admin_context.setdefault("opts", self.model._meta)
        admin_context.setdefault("original", None)

        return TemplateResponse(request, self.change_list_template, admin_context)

    def download_template(self, request):
        if not request.user.is_staff:
            return HttpResponseForbidden("Anda tidak memiliki akses.")

        try:
            import openpyxl
            from openpyxl.workbook import Workbook
        except Exception as e:
            return HttpResponse(f"openpyxl tidak tersedia: {e}", status=500)

        wb = Workbook()
        ws = wb.active
        ws.title = "Template"

        headers = ["nisn", "full_name", "kelas", "status", "issued_date", "nomor_sk"]
        ws.append(headers)

        # contoh row kosong
        ws.append(["1234567890", "Nama Siswa", "VII-A", "L", "2026-01-01", ""])

        # style header
        for col in range(1, len(headers) + 1):
            ws.cell(row=1, column=col).font = openpyxl.styles.Font(bold=True)

        import io

        output = io.BytesIO()
        wb.save(output)
        output.seek(0)

        response = HttpResponse(
            output.getvalue(),
            content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        )
        response["Content-Disposition"] = 'attachment; filename="template_import_kelulusan.xlsx"'
        return response

    def import_excel(self, request):
        if not request.user.is_staff:
            return HttpResponseForbidden("Anda tidak memiliki akses.")

        result = None
        template_name = "admin/kelulusan/student/import_result.html"

        if request.method == "POST" and request.FILES.get("file"):
            upload = request.FILES["file"]
            filename = upload.name.lower()

            try:
                import pandas as pd
            except Exception as e:
                result = {
                    "ok": False,
                    "message": f"pandas tidak tersedia: {e}",
                    "created": 0,
                    "updated": 0,
                    "skipped": 0,
                    "errors": 1,
                }
            else:
                try:
                    if filename.endswith(".csv"):
                        df = pd.read_csv(upload)
                    else:
                        df = pd.read_excel(upload)
                except Exception as e:
                    result = {
                        "ok": False,
                        "message": f"Gagal membaca file Excel: {e}",
                        "created": 0,
                        "updated": 0,
                        "skipped": 0,
                        "errors": 1,
                    }
                else:
                    required = ["nisn", "full_name", "kelas", "status", "issued_date"]
                    missing = [c for c in required if c not in df.columns]
                    if missing:
                        result = {
                            "ok": False,
                            "message": f"Kolom wajib tidak ditemukan: {', '.join(missing)}",
                            "created": 0,
                            "updated": 0,
                            "skipped": 0,
                            "errors": 1,
                        }
                    else:
                        from django.utils.dateparse import parse_date

                        created = 0
                        updated = 0
                        skipped = 0
                        errors = 0

                        for _, row in df.iterrows():
                            try:
                                nisn = str(row.get("nisn", "")).strip()
                                full_name = str(row.get("full_name", "")).strip()
                                kelas = "" if pd.isna(row.get("kelas")) else str(row.get("kelas")).strip()
                                status_raw = row.get("status")

                                if not nisn or not full_name:
                                    skipped += 1
                                    continue

                                status = "T"
                                if isinstance(status_raw, str):
                                    status_clean = status_raw.strip().upper()
                                    if status_clean in ["L", "T"]:
                                        status = status_clean

                                issued_raw = row.get("issued_date")
                                issued_date = None
                                if not pd.isna(issued_raw):
                                    if hasattr(issued_raw, "to_pydatetime"):
                                        issued_date = issued_raw.to_pydatetime().date()
                                    else:
                                        issued_date = parse_date(str(issued_raw).strip())

                                nomor_sk = ""
                                if "nomor_sk" in df.columns:
                                    nomor_sk_raw = row.get("nomor_sk")
                                    nomor_sk = "" if pd.isna(nomor_sk_raw) else str(nomor_sk_raw).strip()

                                if not nomor_sk:
                                    tahun = dj_timezone.now().year
                                    nomor_sk = f"SK-LULUS-{tahun}-{nisn}"

                                student, was_created = Student.objects.get_or_create(nisn=nisn, defaults={})
                                if was_created:
                                    created += 1

                                student.full_name = full_name
                                student.kelas = kelas
                                student.status = status
                                student.issued_date = issued_date
                                student.nomor_sk = nomor_sk
                                student.save()

                                if not was_created:
                                    updated += 1
                            except Exception:
                                errors += 1

                        result = {
                            "ok": True,
                            "message": f"Import selesai.",
                            "created": created,
                            "updated": updated,
                            "skipped": skipped,
                            "errors": errors,
                        }

        # Hindari ketergantungan template admin yang memicu reverse `app_list` (NoReverseMatch saat POST).
        if request.method == "POST":
            back_url = "/admin/kelulusan/student/"
            download_url = "/admin/kelulusan/student/download-template/"

            created = 0 if not result else result.get("created", 0)
            updated = 0 if not result else result.get("updated", 0)
            skipped = 0 if not result else result.get("skipped", 0)
            errors = 0 if not result else result.get("errors", 0)
            message = "" if not result else result.get("message", "")

            result_html = ""
            if result:
                if result.get("ok") and created:
                    result_html = f"""
                      <div style="margin-top: 16px; padding: 12px; border: 1px solid #d4edda; background:#dff7e3; border-radius:6px;">
                        <div style="font-weight:700;">Successfully create {created} student</div>
                      </div>
                    """
                elif result.get("ok"):
                    result_html = f"""
                      <div style="margin-top: 16px; padding: 12px; border: 1px solid #d4edda; background:#dff7e3; border-radius:6px;">
                        <div style="font-weight:700;">Successfully import completed</div>
                        <div style="margin-top:6px; font-size:12px; color:#3b3b3b;">
                          Created: {created} | Updated: {updated} | Skipped: {skipped} | Errors: {errors}
                        </div>
                      </div>
                    """
                else:
                    result_html = f"""
                      <div style="margin-top: 16px; padding: 12px; border: 1px solid #f5c2c7; background:#ffe8ea; border-radius:6px;">
                        <div style="font-weight:700;">Import failed</div>
                        <div style="margin-top:6px;">{message}</div>
                      </div>
                    """

            html = f"""<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Import Data Kelulusan</title>
  </head>
  <body style="font-family: sans-serif; padding: 16px;">
    <h2>Student - Import & Template</h2>

    <div style="margin: 12px 0;">
      <a href="{download_url}" style="display:inline-block;padding:8px 14px;background:#5c6ac4;color:#fff;border-radius:4px;text-decoration:none;font-weight:600;">
        Download Excel Template
      </a>
      <a href="{back_url}" style="margin-left: 10px; display:inline-block; padding:8px 14px; border:1px solid #ccc; border-radius:4px; text-decoration:none;">
        Kembali
      </a>
    </div>

    <form method="post" enctype="multipart/form-data" action="">
      <div style="margin: 12px 0;">
        <input type="file" name="file" accept=".xlsx,.xls,.csv" required />
        <button type="submit" style="margin-left: 8px; padding: 8px 14px;">Upload & Import</button>
      </div>
    </form>

    {result_html}
  </body>
</html>"""
            return redirect("/admin/kelulusan/student/")

        context = {
            "result": result,
            "title": "Import Data Kelulusan",
        }
        return TemplateResponse(request, template_name, context)
