import csv
import datetime
import random
from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse, JsonResponse
from django.contrib import messages
from django.db import IntegrityError
from openpyxl import Workbook
from .models import (
    ProgramStudi, Dosen, TahunAkademik, Hari, 
    MataKuliah, Ruangan, Kelas, Jam, DosenPengampu, Jadwal, DaftarHadir
)

def dashboard(request):
    context = {
        "count_prodi": ProgramStudi.objects.count(),
        "count_dosen": Dosen.objects.count(),
        "count_matkul": MataKuliah.objects.count(),
        "count_ruangan": Ruangan.objects.count(),
        "count_kelas": Kelas.objects.count(),
        "count_jadwal": Jadwal.objects.count(),
        "count_daftar_hadir": DaftarHadir.objects.count(),
    }
    return render(request, "core/dashboard.html", context)

# --- AJAX HELPERS ---
def get_kelas_by_prodi(request):
    prodi_id = request.GET.get('prodi_id')
    kelas = Kelas.objects.filter(prodi_id=prodi_id).values('id', 'nama')
    return JsonResponse(list(kelas), safe=False)

def get_matkul_by_prodi(request):
    prodi_id = request.GET.get('prodi_id')
    matkul = MataKuliah.objects.filter(prodi_id=prodi_id).values('id', 'kode', 'nama')
    return JsonResponse(list(matkul), safe=False)

# --- PRODI ---
def prodi_list(request):
    prodi_all = ProgramStudi.objects.all()
    if request.method == "POST":
        if "delete_massal" in request.POST:
            ids = request.POST.getlist("selected_ids")
            ProgramStudi.objects.filter(id__in=ids).delete()
            messages.success(request, f"Berhasil menghapus {len(ids)} Program Studi.")
        else:
            pk = request.POST.get("pk")
            nama = request.POST.get("nama")
            if pk:
                obj = get_object_or_404(ProgramStudi, pk=pk)
                obj.nama = nama
                obj.save()
                messages.success(request, "Program Studi berhasil diupdate.")
            else:
                ProgramStudi.objects.create(nama=nama)
                messages.success(request, "Program Studi berhasil ditambahkan.")
        return redirect("prodi_list")
    return render(request, "core/prodi_list.html", {"prodi_all": prodi_all})

def prodi_delete(request, pk):
    get_object_or_404(ProgramStudi, pk=pk).delete()
    messages.success(request, "Program Studi berhasil dihapus.")
    return redirect("prodi_list")

# --- DOSEN ---
def dosen_list(request):
    dosen_all = Dosen.objects.all()
    if request.method == "POST":
        if "delete_massal" in request.POST:
            ids = request.POST.getlist("selected_ids")
            Dosen.objects.filter(id__in=ids).delete()
            messages.success(request, f"Berhasil menghapus {len(ids)} Dosen.")
        else:
            pk = request.POST.get("pk")
            nidn = request.POST.get("nidn")
            nama = request.POST.get("nama")
            if pk:
                obj = get_object_or_404(Dosen, pk=pk)
                obj.nidn = nidn
                obj.nama = nama
                obj.save()
                messages.success(request, "Dosen berhasil diupdate.")
            else:
                Dosen.objects.create(nidn=nidn, nama=nama)
                messages.success(request, "Dosen berhasil ditambahkan.")
        return redirect("dosen_list")
    return render(request, "core/dosen_list.html", {"dosen_all": dosen_all})

def dosen_delete(request, pk):
    get_object_or_404(Dosen, pk=pk).delete()
    messages.success(request, "Dosen berhasil dihapus.")
    return redirect("dosen_list")

def dosen_template(request):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="template_dosen.csv"'
    writer = csv.writer(response)
    writer.writerow(['nidn', 'nama'])
    writer.writerow(['12345678', 'Dr. Nama Dosen, M.Kom'])
    return response

def dosen_import(request):
    if request.method == 'POST' and request.FILES.get('csv_file'):
        csv_file = request.FILES['csv_file']
        decoded_file = csv_file.read().decode('utf-8').splitlines()
        reader = csv.DictReader(decoded_file)
        count = 0
        for row in reader:
            Dosen.objects.update_or_create(
                nidn=row['nidn'],
                defaults={'nama': row['nama']}
            )
            count += 1
        messages.success(request, f"Berhasil mengimport {count} data Dosen.")
    return redirect('dosen_list')

# --- MATA KULIAH ---
def matkul_list(request):
    matkul_all = MataKuliah.objects.all()
    prodi_all = ProgramStudi.objects.all()
    if request.method == "POST":
        if "delete_massal" in request.POST:
            ids = request.POST.getlist("selected_ids")
            MataKuliah.objects.filter(id__in=ids).delete()
            messages.success(request, f"Berhasil menghapus {len(ids)} Mata Kuliah.")
        else:
            pk = request.POST.get("pk")
            kode = request.POST.get("kode")
            nama = request.POST.get("nama")
            sks = request.POST.get("sks")
            semester = request.POST.get("semester")
            prodi_id = request.POST.get("prodi")
            prodi = get_object_or_404(ProgramStudi, id=prodi_id)
            try:
                if pk:
                    obj = get_object_or_404(MataKuliah, pk=pk)
                    obj.kode = kode
                    obj.nama = nama
                    obj.sks = sks
                    obj.semester = semester
                    obj.prodi = prodi
                    obj.save()
                    messages.success(request, "Mata Kuliah berhasil diupdate.")
                else:
                    MataKuliah.objects.create(kode=kode, nama=nama, sks=sks, semester=semester, prodi=prodi)
                    messages.success(request, "Mata Kuliah berhasil ditambahkan.")
            except IntegrityError:
                messages.error(request, "Gagal menyimpan. Kode atau Nama Mata Kuliah sudah ada di Program Studi ini.")
        return redirect("matkul_list")
    return render(request, "core/matkul_list.html", {"matkul_all": matkul_all, "prodi_all": prodi_all})

def matkul_delete(request, pk):
    get_object_or_404(MataKuliah, pk=pk).delete()
    messages.success(request, "Mata Kuliah berhasil dihapus.")
    return redirect("matkul_list")

def matkul_template(request):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="template_matkul.csv"'
    writer = csv.writer(response)
    writer.writerow(['kode', 'nama', 'sks', 'semester', 'program_studi'])
    writer.writerow(['MK001', 'Algoritma Pemrograman', '3', '1', 'Teknik Informatika'])
    return response

def matkul_import(request):
    if request.method == 'POST' and request.FILES.get('csv_file'):
        csv_file = request.FILES['csv_file']
        decoded_file = csv_file.read().decode('utf-8').splitlines()
        reader = csv.DictReader(decoded_file)
        count = 0
        for row in reader:
            prodi_nama = row.get('program_studi')
            prodi, _ = ProgramStudi.objects.get_or_create(nama=prodi_nama)
            MataKuliah.objects.update_or_create(
                kode=row['kode'],
                prodi=prodi,
                defaults={
                    'nama': row['nama'],
                    'sks': row['sks'],
                    'semester': row['semester']
                }
            )
            count += 1
        messages.success(request, f"Berhasil mengimport {count} data Mata Kuliah.")
    return redirect('matkul_list')

# --- RUANGAN ---
def ruangan_list(request):
    ruangan_all = Ruangan.objects.all()
    prodi_all = ProgramStudi.objects.all()
    if request.method == "POST":
        if "delete_massal" in request.POST:
            ids = request.POST.getlist("selected_ids")
            Ruangan.objects.filter(id__in=ids).delete()
            messages.success(request, f"Berhasil menghapus {len(ids)} Ruangan.")
        else:
            pk = request.POST.get("pk")
            nama = request.POST.get("nama")
            kapasitas = request.POST.get("kapasitas")
            prodi_id = request.POST.get("prodi")
            prodi = get_object_or_404(ProgramStudi, id=prodi_id) if prodi_id else None
            if pk:
                obj = get_object_or_404(Ruangan, pk=pk)
                obj.nama = nama
                obj.kapasitas = kapasitas
                obj.prodi = prodi
                obj.save()
                messages.success(request, "Ruangan berhasil diupdate.")
            else:
                Ruangan.objects.create(nama=nama, kapasitas=kapasitas, prodi=prodi)
                messages.success(request, "Ruangan berhasil ditambahkan.")
        return redirect("ruangan_list")
    return render(request, "core/ruangan_list.html", {"ruangan_all": ruangan_all, "prodi_all": prodi_all})

def ruangan_delete(request, pk):
    get_object_or_404(Ruangan, pk=pk).delete()
    messages.success(request, "Ruangan berhasil dihapus.")
    return redirect("ruangan_list")

def ruangan_template(request):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="template_ruangan.csv"'
    writer = csv.writer(response)
    writer.writerow(['nama', 'kapasitas', 'program_studi'])
    writer.writerow(['Ruang A1', '40', 'Teknik Informatika'])
    return response

def ruangan_import(request):
    if request.method == 'POST' and request.FILES.get('csv_file'):
        csv_file = request.FILES['csv_file']
        decoded_file = csv_file.read().decode('utf-8').splitlines()
        reader = csv.DictReader(decoded_file)
        count = 0
        for row in reader:
            prodi_nama = row.get('program_studi')
            prodi = None
            if prodi_nama:
                prodi, _ = ProgramStudi.objects.get_or_create(nama=prodi_nama)
            Ruangan.objects.create(nama=row['nama'], kapasitas=row['kapasitas'], prodi=prodi)
            count += 1
        messages.success(request, f"Berhasil mengimport {count} data Ruangan.")
    return redirect('ruangan_list')

# --- KELAS ---
def kelas_list(request):
    kelas_all = Kelas.objects.all()
    prodi_all = ProgramStudi.objects.all()
    if request.method == "POST":
        if "delete_massal" in request.POST:
            ids = request.POST.getlist("selected_ids")
            Kelas.objects.filter(id__in=ids).delete()
            messages.success(request, f"Berhasil menghapus {len(ids)} Kelas.")
        else:
            pk = request.POST.get("pk")
            nama = request.POST.get("nama")
            prodi_id = request.POST.get("prodi")
            prodi = get_object_or_404(ProgramStudi, id=prodi_id) if prodi_id else None
            if pk:
                obj = get_object_or_404(Kelas, pk=pk)
                obj.nama = nama
                obj.prodi = prodi
                obj.save()
                messages.success(request, "Kelas berhasil diupdate.")
            else:
                Kelas.objects.create(nama=nama, prodi=prodi)
                messages.success(request, "Kelas berhasil ditambahkan.")
        return redirect("kelas_list")
    return render(request, "core/kelas_list.html", {"kelas_all": kelas_all, "prodi_all": prodi_all})

def kelas_delete(request, pk):
    get_object_or_404(Kelas, pk=pk).delete()
    messages.success(request, "Kelas berhasil dihapus.")
    return redirect("kelas_list")

def kelas_template(request):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="template_kelas.csv"'
    writer = csv.writer(response)
    writer.writerow(['nama', 'program_studi'])
    writer.writerow(['Kelas A', 'Teknik Informatika'])
    return response

def kelas_import(request):
    if request.method == 'POST' and request.FILES.get('csv_file'):
        csv_file = request.FILES['csv_file']
        decoded_file = csv_file.read().decode('utf-8').splitlines()
        reader = csv.DictReader(decoded_file)
        count = 0
        for row in reader:
            prodi_nama = row.get('program_studi')
            prodi = None
            if prodi_nama:
                prodi, _ = ProgramStudi.objects.get_or_create(nama=prodi_nama)
            Kelas.objects.create(nama=row['nama'], prodi=prodi)
            count += 1
        messages.success(request, f"Berhasil mengimport {count} data Kelas.")
    return redirect('kelas_list')

# --- JAM ---
def jam_list(request):
    jam_all = Jam.objects.all()
    if request.method == "POST":
        if "delete_massal" in request.POST:
            ids = request.POST.getlist("selected_ids")
            Jam.objects.filter(id__in=ids).delete()
            messages.success(request, f"Berhasil menghapus {len(ids)} Jam.")
        else:
            pk = request.POST.get("pk")
            range_waktu = request.POST.get("range_waktu")
            if pk:
                obj = get_object_or_404(Jam, pk=pk)
                obj.range_waktu = range_waktu
                obj.save()
                messages.success(request, "Jam berhasil diupdate.")
            else:
                Jam.objects.create(range_waktu=range_waktu)
                messages.success(request, "Jam berhasil ditambahkan.")
        return redirect("jam_list")
    return render(request, "core/jam_list.html", {"jam_all": jam_all})

def jam_delete(request, pk):
    get_object_or_404(Jam, pk=pk).delete()
    messages.success(request, "Jam berhasil dihapus.")
    return redirect("jam_list")

def jam_generate(request):
    if request.method == "POST":
        start_str = request.POST.get("jam_mulai") # e.g. "07:00"
        end_str = request.POST.get("jam_selesai") # e.g. "17:00"
        mins_per_sks = int(request.POST.get("durasi_per_sks", 50))
        sks_per_slot = int(request.POST.get("jumlah_sks", 2))
        jeda_mins = int(request.POST.get("jeda", 0))
        
        start_time = datetime.datetime.strptime(start_str, "%H:%M")
        end_time = datetime.datetime.strptime(end_str, "%H:%M")
        
        slot_duration = mins_per_sks * sks_per_slot
        current_time = start_time
        
        count = 0
        while current_time + datetime.timedelta(minutes=slot_duration) <= end_time:
            slot_end = current_time + datetime.timedelta(minutes=slot_duration)
            range_waktu = f"{current_time.strftime('%H:%M')} - {slot_end.strftime('%H:%M')}"
            Jam.objects.get_or_create(range_waktu=range_waktu)
            current_time = slot_end + datetime.timedelta(minutes=jeda_mins)
            count += 1
            
        messages.success(request, f"Berhasil menggenerate {count} slot waktu.")
    return redirect("jam_list")

# --- TAHUN AKADEMIK ---
def tahun_list(request):
    tahun_all = TahunAkademik.objects.all()
    if request.method == "POST":
        if "delete_massal" in request.POST:
            ids = request.POST.getlist("selected_ids")
            TahunAkademik.objects.filter(id__in=ids).delete()
            messages.success(request, f"Berhasil menghapus {len(ids)} Tahun Akademik.")
        else:
            pk = request.POST.get("pk")
            nama = request.POST.get("nama")
            is_active = request.POST.get("is_active") == "on"
            if pk:
                obj = get_object_or_404(TahunAkademik, pk=pk)
                if is_active:
                    TahunAkademik.objects.update(is_active=False)
                obj.nama = nama
                obj.is_active = is_active
                obj.save()
                messages.success(request, "Tahun Akademik berhasil diupdate.")
            else:
                if is_active:
                    TahunAkademik.objects.update(is_active=False)
                TahunAkademik.objects.create(nama=nama, is_active=is_active)
                messages.success(request, "Tahun Akademik berhasil ditambahkan.")
        return redirect("tahun_list")
    return render(request, "core/tahun_list.html", {"tahun_all": tahun_all})

def tahun_delete(request, pk):
    get_object_or_404(TahunAkademik, pk=pk).delete()
    messages.success(request, "Tahun Akademik berhasil dihapus.")
    return redirect("tahun_list")

# --- HARI ---
def hari_list(request):
    hari_all = Hari.objects.all()
    if request.method == "POST":
        if "delete_massal" in request.POST:
            ids = request.POST.getlist("selected_ids")
            Hari.objects.filter(id__in=ids).delete()
            messages.success(request, f"Berhasil menghapus {len(ids)} Hari.")
        else:
            pk = request.POST.get("pk")
            nama = request.POST.get("nama")
            if pk:
                obj = get_object_or_404(Hari, pk=pk)
                obj.nama = nama
                obj.save()
                messages.success(request, "Hari berhasil diupdate.")
            else:
                Hari.objects.create(nama=nama)
                messages.success(request, "Hari berhasil ditambahkan.")
        return redirect("hari_list")
    return render(request, "core/hari_list.html", {"hari_all": hari_all})

def hari_delete(request, pk):
    get_object_or_404(Hari, pk=pk).delete()
    messages.success(request, "Hari berhasil dihapus.")
    return redirect("hari_list")

# --- DOSEN PENGAMPU ---
def pengampu_list(request):
    pengampu_all = DosenPengampu.objects.all()
    dosen_all = Dosen.objects.all()
    matkul_all = MataKuliah.objects.all()
    tahun_all = TahunAkademik.objects.all()
    prodi_all = ProgramStudi.objects.all()
    kelas_all = Kelas.objects.all()
    if request.method == "POST":
        if "delete_massal" in request.POST:
            ids = request.POST.getlist("selected_ids")
            DosenPengampu.objects.filter(id__in=ids).delete()
            messages.success(request, f"Berhasil menghapus {len(ids)} Dosen Pengampu.")
        else:
            pk = request.POST.get("pk")
            dosen_id = request.POST.get("dosen")
            matkul_id = request.POST.get("matkul")
            tahun_id = request.POST.get("tahun")
            prodi_id = request.POST.get("prodi")
            kelas_id = request.POST.get("kelas")
            
            dosen = get_object_or_404(Dosen, id=dosen_id)
            matkul = get_object_or_404(MataKuliah, id=matkul_id)
            tahun = get_object_or_404(TahunAkademik, id=tahun_id)
            prodi = get_object_or_404(ProgramStudi, id=prodi_id) if prodi_id else None
            kelas = get_object_or_404(Kelas, id=kelas_id) if kelas_id else None
            
            if pk:
                obj = get_object_or_404(DosenPengampu, pk=pk)
                obj.dosen = dosen
                obj.matkul = matkul
                obj.tahun_akademik = tahun
                obj.prodi = prodi
                obj.kelas = kelas
                obj.save()
                messages.success(request, "Dosen Pengampu berhasil diupdate.")
            else:
                DosenPengampu.objects.create(
                    dosen=dosen, matkul=matkul, tahun_akademik=tahun,
                    prodi=prodi, kelas=kelas
                )
                messages.success(request, "Dosen Pengampu berhasil ditambahkan.")
        return redirect("pengampu_list")
    return render(request, "core/pengampu_list.html", {
        "pengampu_all": pengampu_all,
        "dosen_all": dosen_all,
        "matkul_all": matkul_all,
        "tahun_all": tahun_all,
        "prodi_all": prodi_all,
        "kelas_all": kelas_all,
    })

def pengampu_delete(request, pk):
    get_object_or_404(DosenPengampu, pk=pk).delete()
    messages.success(request, "Dosen Pengampu berhasil dihapus.")
    return redirect("pengampu_list")

# --- DAFTAR HADIR ---
def daftar_hadir_list(request):
    hadir_all = DaftarHadir.objects.all()
    jadwal_all = Jadwal.objects.all()
    if request.method == "POST":
        if "delete_massal" in request.POST:
            ids = request.POST.getlist("selected_ids")
            DaftarHadir.objects.filter(id__in=ids).delete()
            messages.success(request, f"Berhasil menghapus {len(ids)} Daftar Hadir.")
        else:
            pk = request.POST.get("pk")
            jadwal_id = request.POST.get("jadwal")
            tanggal = request.POST.get("tanggal")
            pertemuan = request.POST.get("pertemuan_ke")
            ket = request.POST.get("keterangan")
            jadwal = get_object_or_404(Jadwal, id=jadwal_id)
            if pk:
                obj = get_object_or_404(DaftarHadir, pk=pk)
                obj.jadwal = jadwal
                obj.tanggal = tanggal
                obj.pertemuan_ke = pertemuan
                obj.keterangan = ket
                obj.save()
                messages.success(request, "Daftar Hadir berhasil diupdate.")
            else:
                DaftarHadir.objects.create(jadwal=jadwal, tanggal=tanggal, pertemuan_ke=pertemuan, keterangan=ket)
                messages.success(request, "Daftar Hadir berhasil ditambahkan.")
        return redirect("daftar_hadir_list")
    return render(request, "core/daftar_hadir_list.html", {"hadir_all": hadir_all, "jadwal_all": jadwal_all})

def daftar_hadir_delete(request, pk):
    get_object_or_404(DaftarHadir, pk=pk).delete()
    messages.success(request, "Daftar Hadir berhasil dihapus.")
    return redirect("daftar_hadir_list")

# --- JADWAL ---
def jadwal_list(request):
    jadwal_all = Jadwal.objects.all().order_by('hari', 'jam')
    pengampu_all = DosenPengampu.objects.all()
    ruangan_all = Ruangan.objects.all()
    hari_all = Hari.objects.all()
    jam_all = Jam.objects.all()
    kelas_all = Kelas.objects.all()
    
    if request.method == "POST":
        if "delete_massal" in request.POST:
            ids = request.POST.getlist("selected_ids")
            Jadwal.objects.filter(id__in=ids).delete()
            messages.success(request, f"Berhasil menghapus {len(ids)} Jadwal.")
        else:
            pk = request.POST.get("pk")
            pengampu_id = request.POST.get("pengampu")
            ruangan_id = request.POST.get("ruangan")
            hari_id = request.POST.get("hari")
            jam_id = request.POST.get("jam")
            kelas_id = request.POST.get("kelas")
            
            pengampu = get_object_or_404(DosenPengampu, id=pengampu_id)
            ruangan = get_object_or_404(Ruangan, id=ruangan_id)
            hari = get_object_or_404(Hari, id=hari_id)
            jam = get_object_or_404(Jam, id=jam_id)
            kelas = get_object_or_404(Kelas, id=kelas_id)
            
            if pk:
                obj = get_object_or_404(Jadwal, pk=pk)
                obj.dosen_pengampu = pengampu
                obj.ruangan = ruangan
                obj.hari = hari
                obj.jam = jam
                obj.kelas = kelas
                obj.save()
                messages.success(request, "Jadwal berhasil diupdate.")
            else:
                Jadwal.objects.create(
                    dosen_pengampu=pengampu, ruangan=ruangan,
                    hari=hari, jam=jam, kelas=kelas, is_manual=True
                )
                messages.success(request, "Jadwal berhasil ditambahkan secara manual.")
        return redirect("jadwal_list")
        
    return render(request, "core/jadwal_list.html", {
        "jadwal_all": jadwal_all,
        "pengampu_all": pengampu_all,
        "ruangan_all": ruangan_all,
        "hari_all": hari_all,
        "jam_all": jam_all,
        "kelas_all": kelas_all,
    })

def buat_jadwal(request):
    if request.method == "POST":
        pengampu_all = DosenPengampu.objects.all()
        ruangan_all = Ruangan.objects.all()
        hari_all = Hari.objects.all()
        jam_all = Jam.objects.all()

        if not (pengampu_all and ruangan_all and hari_all and jam_all):
            messages.error(request, "Data Master belum lengkap.")
            return redirect("buat_jadwal")

        # Only delete schedules that were not manually created
        Jadwal.objects.filter(is_manual=False).delete()
        
        # Get pengampu that don't have a schedule yet (including manual ones)
        pengampu_with_jadwal = Jadwal.objects.values_list('dosen_pengampu_id', flat=True)
        pending_pengampu = pengampu_all.exclude(id__in=pengampu_with_jadwal)

        for pengampu in pending_pengampu:
            # We use the class assigned in DosenPengampu
            kelas = pengampu.kelas
            if not kelas:
                # Fallback to random class if not assigned in Pengampu (for legacy data)
                kelas_all = Kelas.objects.all()
                kelas = random.choice(kelas_all) if kelas_all.exists() else None
            
            if not kelas: continue

            # Simple logic to find an available slot (avoiding collisions for manual ones)
            # This is still a basic random generator but it now respects existing manual entries
            max_tries = 50
            for _ in range(max_tries):
                h = random.choice(hari_all)
                j = random.choice(jam_all)
                r = random.choice(ruangan_all)
                
                # Check for collisions in that room/time
                if not Jadwal.objects.filter(hari=h, jam=j, ruangan=r).exists() and \
                   not Jadwal.objects.filter(hari=h, jam=j, kelas=kelas).exists() and \
                   not Jadwal.objects.filter(hari=h, jam=j, dosen_pengampu__dosen=pengampu.dosen).exists():
                    
                    Jadwal.objects.create(
                        dosen_pengampu=pengampu,
                        ruangan=r,
                        hari=h,
                        jam=j,
                        kelas=kelas,
                        is_manual=False
                    )
                    break
        
        messages.success(request, "Jadwal berhasil digenerate otomatis (menghindari jadwal manual).")
        return redirect("jadwal_list")
    return render(request, "core/buat_jadwal.html")

def jadwal_delete(request, pk):
    get_object_or_404(Jadwal, pk=pk).delete()
    messages.success(request, "Jadwal berhasil dihapus.")
    return redirect("jadwal_list")

def jadwal_export_excel(request):
    wb = Workbook()
    ws = wb.active
    ws.title = "Jadwal Kuliah"
    
    headers = [
        'No', 'Hari', 'Jam', 'Kode MK', 'Mata Kuliah', 'SKS', 'Semester', 
        'Dosen', 'Kelas', 'Ruangan', 'Program Studi', 'Tahun Akademik'
    ]
    ws.append(headers)
    
    jadwal_all = Jadwal.objects.all().select_related(
        'hari', 'jam', 'dosen_pengampu__matkul', 'dosen_pengampu__dosen', 
        'kelas', 'ruangan', 'dosen_pengampu__matkul__prodi', 'dosen_pengampu__tahun_akademik'
    ).order_by('hari', 'jam')
    
    for i, j in enumerate(jadwal_all, 1):
        ws.append([
            i,
            j.hari.nama,
            j.jam.range_waktu,
            j.dosen_pengampu.matkul.kode,
            j.dosen_pengampu.matkul.nama,
            j.dosen_pengampu.matkul.sks,
            j.dosen_pengampu.matkul.semester,
            j.dosen_pengampu.dosen.nama,
            j.kelas.nama,
            j.ruangan.nama,
            j.dosen_pengampu.matkul.prodi.nama,
            j.dosen_pengampu.tahun_akademik.nama
        ])
    
    response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    response['Content-Disposition'] = 'attachment; filename="jadwal_kuliah.xlsx"'
    wb.save(response)
    return response
