<?php
require_once __DIR__ . '/../models/NilaiModel.php';
require_once __DIR__ . '/../models/KelasModel.php';
require_once __DIR__ . '/../models/SiswaModel.php';

/**
 * Controller Nilai Rapor
 */
class NilaiController {

    private $model;
    private $kelasModel;
    private $siswaModel;

    // Label semester 1-6
    private $semesterList = [
        1 => 'Semester 1 (Ganjil - Kelas VII)',
        2 => 'Semester 2 (Genap  - Kelas VII)',
        3 => 'Semester 3 (Ganjil - Kelas VIII)',
        4 => 'Semester 4 (Genap  - Kelas VIII)',
        5 => 'Semester 5 (Ganjil - Kelas IX)',
        6 => 'Semester 6 (Genap  - Kelas IX)',
    ];

    public function __construct() {
        $this->model      = new NilaiModel();
        $this->kelasModel = new KelasModel();
        $this->siswaModel = new SiswaModel();
    }

    private function getPengaturan() {
        $db  = getDB();
        $row = query_fetch_assoc($db, "SELECT * FROM pengaturan LIMIT 1");
        return $row ?? ['tahun_ajaran' => '2024/2025'];
    }

    // ----------------------------------------------------------------
    // Daftar Nilai — Rekap per siswa semua semester (tanpa filter tahun)
    // ----------------------------------------------------------------
    public function index() {
        $kelasList = $this->kelasModel->getAllSimple();
        $kelasId   = (int)($_GET['kelas_id'] ?? 0);
        $siswaId   = (int)($_GET['siswa_id'] ?? 0);

        $siswaList  = [];
        $siswa      = null;
        $rekap      = [];
        $rataPerSmt = [];
        $kelas      = null;

        // Jika kelas dipilih, load daftar siswa
        if ($kelasId) {
            $kelas     = $this->kelasModel->getById($kelasId);
            $siswaList = $this->model->getSiswaByKelas($kelasId);
        }

        // Jika siswa dipilih, load rekap nilai (semua tahun/semester)
        if ($siswaId && $kelasId) {
            $siswa      = $this->siswaModel->getById($siswaId);
            $rekap      = $this->model->getRekapNilaiSiswa($siswaId);
            $rataPerSmt = $this->model->getRataPerSemester($siswaId);
        }

        $flash     = getFlash();
        $pageTitle = 'Daftar Nilai';
        include __DIR__ . '/../views/nilai/index.php';
    }

    // AJAX: ambil siswa berdasarkan kelas
    public function getSiswaAjax() {
        $kelasId = (int)($_GET['kelas_id'] ?? 0);
        header('Content-Type: application/json');
        if (!$kelasId) { echo json_encode([]); exit; }
        $siswa = $this->model->getSiswaByKelas($kelasId);
        echo json_encode($siswa);
        exit;
    }

    // ----------------------------------------------------------------
    // Input Nilai (manual per mapel)
    // ----------------------------------------------------------------
    public function input() {
        $kelasList   = $this->kelasModel->getAllSimple();
        $mapelList   = $this->model->getAllMapel();
        $kelasId     = (int)($_GET['kelas_id'] ?? 0);
        $mapelId     = (int)($_GET['mapel_id'] ?? 0);
        $pg          = $this->getPengaturan();
        $tahunAjaran = sanitize($_GET['tahun_ajaran'] ?? $pg['tahun_ajaran']);
        $semesterNo  = max(1, min(6, (int)($_GET['semester_no'] ?? 1)));

        $siswaList     = [];
        $existingNilai = [];

        if ($kelasId) {
            $siswaList = $this->kelasModel->getSiswaByKelas($kelasId);
            if ($mapelId) {
                $rows = $this->model->getByKelasMapel($kelasId, $mapelId, $tahunAjaran, $semesterNo);
                foreach ($rows as $r) {
                    $existingNilai[$r['siswa_id']] = $r;
                }
            }
        }

        $errors = [];

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            if (!validateCSRF($_POST['csrf_token'] ?? '')) {
                $errors[] = 'Token tidak valid.';
            } else {
                $kelasId     = (int)($_POST['kelas_id'] ?? 0);
                $mapelId     = (int)($_POST['mapel_id'] ?? 0);
                $tahunAjaran = sanitize($_POST['tahun_ajaran'] ?? '');
                $semesterNo  = max(1, min(6, (int)($_POST['semester_no'] ?? 1)));
                $nilaiData   = $_POST['nilai'] ?? [];

                if (!$kelasId || !$mapelId) {
                    $errors[] = 'Kelas dan Mata Pelajaran wajib dipilih.';
                } else {
                    $saved = 0;
                    foreach ($nilaiData as $sid => $n) {
                        $val = trim($n['nilai_rapor'] ?? '');
                        if ($val === '') continue;
                        $this->model->upsert([
                            'siswa_id'    => (int)$sid,
                            'kelas_id'    => $kelasId,
                            'mapel_id'    => $mapelId,
                            'tahun_ajaran'=> $tahunAjaran,
                            'semester_no' => $semesterNo,
                            'nilai_rapor' => (float)$val,
                            'keterangan'  => trim($n['keterangan'] ?? ''),
                        ]);
                        $saved++;
                    }
                    setFlash('success', "$saved nilai rapor berhasil disimpan.");
                    redirect(BASE_URL . '/index.php?page=nilai_input'
                        . '&kelas_id='     . $kelasId
                        . '&mapel_id='     . $mapelId
                        . '&tahun_ajaran=' . urlencode($tahunAjaran)
                        . '&semester_no='  . $semesterNo);
                }
            }
        }

        $semesterList = $this->semesterList;
        $flash        = getFlash();
        $pageTitle    = 'Input Nilai Rapor';
        $csrfToken    = generateCSRF();
        include __DIR__ . '/../views/nilai/input.php';
    }

    // ----------------------------------------------------------------
    // Cetak Rapor
    // ----------------------------------------------------------------
    public function rapor() {
        $kelasList   = $this->kelasModel->getAllSimple();
        $kelasId     = (int)($_GET['kelas_id'] ?? 0);
        $siswaId     = (int)($_GET['siswa_id'] ?? 0);
        $pg          = $this->getPengaturan();
        $tahunAjaran = sanitize($_GET['tahun_ajaran'] ?? $pg['tahun_ajaran']);
        $semesterNo  = max(1, min(6, (int)($_GET['semester_no'] ?? 1)));

        $siswaList = [];
        $siswa     = null;
        $nilai     = [];
        $kelas     = null;

        if ($kelasId) {
            $kelas     = $this->kelasModel->getById($kelasId);
            $siswaList = $this->kelasModel->getSiswaByKelas($kelasId);
        }
        if ($siswaId) {
            $siswa = $this->siswaModel->getById($siswaId);
            $nilai = $this->model->getRaporSiswa($siswaId, $kelasId, $tahunAjaran, $semesterNo);
        }

        $db      = getDB();
        $sekolah = query_fetch_assoc($db, "SELECT * FROM pengaturan LIMIT 1") ?? [];

        $semesterList = $this->semesterList;
        $pageTitle    = 'Cetak Rapor';
        include __DIR__ . '/../views/nilai/rapor.php';
    }

    // ----------------------------------------------------------------
    // Download Template CSV
    // ----------------------------------------------------------------
    public function templateDownload() {
        $kelasId     = (int)($_GET['kelas_id'] ?? 0);
        $semesterNo  = max(1, min(6, (int)($_GET['semester_no'] ?? 1)));
        $tahunAjaran = sanitize($_GET['tahun_ajaran'] ?? '2024/2025');

        if (!$kelasId) {
            setFlash('danger', 'Pilih kelas terlebih dahulu.');
            redirect(BASE_URL . '/index.php?page=nilai_import');
        }

        $kelas     = $this->kelasModel->getById($kelasId);
        $siswaList = $this->kelasModel->getSiswaByKelas($kelasId);
        $mapelList = $this->model->getAllMapel();
        $sLabel    = $this->semesterList[$semesterNo] ?? "Semester $semesterNo";

        $namaFile = 'template_nilai_'
            . preg_replace('/[^a-zA-Z0-9]/', '_', $kelas['nama_kelas'] ?? 'kelas')
            . '_smt' . $semesterNo
            . '_' . str_replace('/', '-', $tahunAjaran)
            . '.csv';

        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="' . $namaFile . '"');
        header('Cache-Control: no-cache');

        $out = fopen('php://output', 'w');
        fputs($out, "\xEF\xBB\xBF");

        // 5 baris info (di-skip saat import)
        fputcsv($out, ['TEMPLATE NILAI RAPOR - JANGAN UBAH 5 BARIS INI']);
        fputcsv($out, ['Kelas',        $kelas['nama_kelas'] ?? '']);
        fputcsv($out, ['Semester',     $sLabel]);
        fputcsv($out, ['Tahun Ajaran', $tahunAjaran]);
        fputcsv($out, ['--- DATA MULAI BARIS 7 ---']);

        // Header kolom: No | NIS | Nama Siswa | [Nama Mapel 1] | [Nama Mapel 2] | ...
        $header = ['No', 'NIS', 'Nama Siswa'];
        foreach ($mapelList as $mp) {
            $header[] = $mp['nama']; // nama lengkap mapel
        }
        fputcsv($out, $header);

        // Data siswa (nilai kosong)
        foreach ($siswaList as $i => $s) {
            $row = [$i + 1, $s['nis'] ?? '', $s['nama']];
            foreach ($mapelList as $mp) {
                $row[] = ''; // nilai rapor kosong, diisi guru
            }
            fputcsv($out, $row);
        }

        fclose($out);
        exit;
    }

    // ----------------------------------------------------------------
    // Import Nilai dari CSV
    // ----------------------------------------------------------------
    public function importNilai() {
        $kelasList    = $this->kelasModel->getAllSimple();
        $semesterList = $this->semesterList;
        $errors       = [];
        $imported     = 0;

        $pg          = $this->getPengaturan();
        $tahunAjaran = sanitize($_GET['tahun_ajaran'] ?? $pg['tahun_ajaran']);
        $semesterNo  = max(1, min(6, (int)($_GET['semester_no'] ?? 1)));
        $kelasId     = (int)($_GET['kelas_id'] ?? 0);

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            if (!validateCSRF($_POST['csrf_token'] ?? '')) {
                $errors[] = 'Token tidak valid.';
            } elseif (empty($_FILES['file']['name']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
                $errors[] = 'Pilih file CSV terlebih dahulu.';
            } else {
                $kelasId     = (int)($_POST['kelas_id'] ?? 0);
                $semesterNo  = max(1, min(6, (int)($_POST['semester_no'] ?? 1)));
                $tahunAjaran = sanitize($_POST['tahun_ajaran'] ?? '2024/2025');

                if (!$kelasId) {
                    $errors[] = 'Pilih kelas terlebih dahulu.';
                } else {
                    $ext = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));
                    if ($ext !== 'csv') {
                        $errors[] = 'Hanya file CSV yang didukung.';
                    } else {
                        // Baca & hapus BOM
                        $content = file_get_contents($_FILES['file']['tmp_name']);
                        $content = ltrim($content, "\xEF\xBB\xBF");
                        $tmp     = tmpfile();
                        fwrite($tmp, $content);
                        rewind($tmp);

                        // Skip 5 baris info
                        for ($i = 0; $i < 5; $i++) fgetcsv($tmp);

                        // Baca header kolom (baris ke-6)
                        $headerRow = fgetcsv($tmp);
                        if (!$headerRow) {
                            $errors[] = 'Format file tidak valid. Gunakan template yang disediakan.';
                        } else {
                            // Map nama mapel => id (berdasarkan NAMA, bukan kode)
                            $mapelAll = $this->model->getAllMapel();
                            $mapelByNama = []; // nama lowercase => id
                            $mapelByKode = []; // kode uppercase => id (fallback)
                            foreach ($mapelAll as $mp) {
                                $mapelByNama[strtolower(trim($mp['nama']))] = $mp['id'];
                                $mapelByKode[strtoupper(trim($mp['kode']))] = $mp['id'];
                            }

                            // Peta kolom: index => mapel_id
                            // Kolom 0=No, 1=NIS, 2=Nama, 3+=nilai rapor per mapel
                            $colMap = [];
                            for ($c = 3; $c < count($headerRow); $c++) {
                                $h   = trim($headerRow[$c]);
                                // Coba cocokkan dengan nama dulu, lalu kode
                                $mid = $mapelByNama[strtolower($h)]
                                    ?? $mapelByKode[strtoupper($h)]
                                    ?? null;
                                if ($mid) $colMap[$c] = $mid;
                            }

                            // Map NIS => siswa_id
                            $siswaAll = $this->kelasModel->getSiswaByKelas($kelasId);
                            $siswaMap = [];
                            foreach ($siswaAll as $s) {
                                $siswaMap[trim($s['nis'])] = $s['id'];
                            }

                            // Baca & simpan nilai
                            while (($row = fgetcsv($tmp)) !== false) {
                                if (count($row) < 3 || empty(trim($row[2]))) continue;
                                $nis     = trim($row[1]);
                                $siswaId = $siswaMap[$nis] ?? null;
                                if (!$siswaId) continue;

                                foreach ($colMap as $c => $mapelId) {
                                    $val = trim($row[$c] ?? '');
                                    if ($val === '') continue;
                                    $val = (float)$val;
                                    if ($val < 0 || $val > 100) continue;

                                    $this->model->upsert([
                                        'siswa_id'    => $siswaId,
                                        'kelas_id'    => $kelasId,
                                        'mapel_id'    => $mapelId,
                                        'tahun_ajaran'=> $tahunAjaran,
                                        'semester_no' => $semesterNo,
                                        'nilai_rapor' => $val,
                                        'keterangan'  => '',
                                    ]);
                                    $imported++;
                                }
                            }
                            fclose($tmp);

                            setFlash('success', "$imported nilai rapor berhasil diimport.");
                            redirect(BASE_URL . '/index.php?page=nilai_import'
                                . '&kelas_id='     . $kelasId
                                . '&semester_no='  . $semesterNo
                                . '&tahun_ajaran=' . urlencode($tahunAjaran));
                        }
                    }
                }
            }
        }

        $flash     = getFlash();
        $pageTitle = 'Import Nilai Rapor';
        $csrfToken = generateCSRF();
        include __DIR__ . '/../views/nilai/import.php';
    }

    // ----------------------------------------------------------------
    // Export Rekap Nilai Siswa (semua semester) ke CSV
    // Dipanggil dari halaman Daftar Nilai
    // ----------------------------------------------------------------
    public function exportRekap() {
        $siswaId = (int)($_GET['siswa_id'] ?? 0);
        $kelasId = (int)($_GET['kelas_id'] ?? 0);

        if (!$siswaId) {
            setFlash('danger', 'Pilih siswa terlebih dahulu.');
            redirect(BASE_URL . '/index.php?page=nilai');
        }

        // Ambil data siswa
        $siswa = $this->siswaModel->getById($siswaId);
        if (!$siswa) {
            setFlash('danger', 'Data siswa tidak ditemukan.');
            redirect(BASE_URL . '/index.php?page=nilai');
        }

        // Ambil rekap nilai semua semester
        $rekap      = $this->model->getRekapNilaiSiswa($siswaId);
        $rataPerSmt = $this->model->getRataPerSemester($siswaId);

        // Nama file
        $namaFile = 'nilai_'
            . preg_replace('/[^a-zA-Z0-9]/', '_', $siswa['nama'])
            . '_' . date('Ymd')
            . '.csv';

        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="' . $namaFile . '"');
        header('Cache-Control: no-cache');

        $out = fopen('php://output', 'w');
        fputs($out, "\xEF\xBB\xBF"); // BOM UTF-8

        // ---- Info siswa ----
        fputcsv($out, ['REKAP NILAI RAPOR']);
        fputcsv($out, ['Nama Siswa', $siswa['nama']]);
        fputcsv($out, ['NIS',        $siswa['nis'] ?? '-']);
        fputcsv($out, ['Kelas',      $siswa['nama_kelas'] ?? '-']);
        fputcsv($out, ['Tanggal Export', date('d/m/Y H:i')]);
        fputcsv($out, []); // baris kosong

        // ---- Header kolom ----
        fputcsv($out, [
            'No',
            'Mata Pelajaran',
            'Semester 1',
            'Semester 2',
            'Semester 3',
            'Semester 4',
            'Semester 5',
            'Semester 6',
            'Rata-rata',
            'Predikat',
        ]);

        // ---- Data nilai per mapel ----
        $no = 1;
        $totalRata  = 0;
        $countRata  = 0;
        $smtTotal   = [1=>0, 2=>0, 3=>0, 4=>0, 5=>0, 6=>0];
        $smtCount   = [1=>0, 2=>0, 3=>0, 4=>0, 5=>0, 6=>0];

        foreach ($rekap as $r) {
            // Skip mapel tanpa nilai
            $hasNilai = false;
            for ($s = 1; $s <= 6; $s++) {
                if ($r['semester'][$s] !== null) { $hasNilai = true; break; }
            }
            if (!$hasNilai) continue;

            $row = [$no++, $r['nama']];
            for ($s = 1; $s <= 6; $s++) {
                $val = $r['semester'][$s];
                $row[] = $val !== null ? number_format((float)$val, 2) : '-';
                if ($val !== null) {
                    $smtTotal[$s] += $val;
                    $smtCount[$s]++;
                }
            }
            $row[] = $r['rata'] !== null ? number_format((float)$r['rata'], 2) : '-';
            $row[] = $r['predikat'] !== '-' ? $r['predikat'] : '-';

            if ($r['rata'] !== null) {
                $totalRata += $r['rata'];
                $countRata++;
            }

            fputcsv($out, $row);
        }

        // ---- Baris rata-rata keseluruhan ----
        fputcsv($out, []); // baris kosong
        $rataRow = ['', 'Rata-rata Keseluruhan'];
        for ($s = 1; $s <= 6; $s++) {
            $rata = $rataPerSmt[$s] ?? null;
            $rataRow[] = $rata !== null ? number_format((float)$rata, 2) : '-';
        }
        $rataAkhir = $countRata > 0 ? round($totalRata / $countRata, 2) : null;
        $predAkhir = '-';
        if ($rataAkhir !== null) {
            if ($rataAkhir >= 90)     $predAkhir = 'A';
            elseif ($rataAkhir >= 80) $predAkhir = 'B';
            elseif ($rataAkhir >= 70) $predAkhir = 'C';
            else                      $predAkhir = 'D';
        }
        $rataRow[] = $rataAkhir !== null ? number_format($rataAkhir, 2) : '-';
        $rataRow[] = $predAkhir;
        fputcsv($out, $rataRow);

        fclose($out);
        exit;
    }

    // ----------------------------------------------------------------
    // Export Nilai ke CSV (per kelas, per semester)
    // ----------------------------------------------------------------
    public function export() {
        $kelasId     = (int)($_GET['kelas_id'] ?? 0);
        $semesterNo  = max(1, min(6, (int)($_GET['semester_no'] ?? 1)));
        $tahunAjaran = sanitize($_GET['tahun_ajaran'] ?? '2024/2025');

        $kelas     = $this->kelasModel->getById($kelasId);
        $mapelList = $this->model->getAllMapel();
        $nilai     = $this->model->getByKelas($kelasId, $tahunAjaran, $semesterNo);

        $namaFile = 'nilai_rapor_'
            . preg_replace('/[^a-zA-Z0-9]/', '_', $kelas['nama_kelas'] ?? 'kelas')
            . '_smt' . $semesterNo . '_' . date('Ymd') . '.csv';

        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="' . $namaFile . '"');
        header('Cache-Control: no-cache');

        $out = fopen('php://output', 'w');
        fputs($out, "\xEF\xBB\xBF");

        // Header — pakai nama lengkap mapel
        $header = ['No', 'NIS', 'Nama Siswa'];
        foreach ($mapelList as $mp) {
            $header[] = $mp['nama'];
        }
        $header[] = 'Rata-rata';
        fputcsv($out, $header);

        // Kelompokkan nilai per siswa per mapel
        $nilaiMap = [];
        foreach ($nilai as $n) {
            $nilaiMap[$n['siswa_id']][$n['mapel_id']] = $n['nilai_rapor'];
        }

        $siswaList = $this->kelasModel->getSiswaByKelas($kelasId);
        $no = 1;
        foreach ($siswaList as $s) {
            $row    = [$no++, $s['nis'] ?? '', $s['nama']];
            $total  = 0;
            $count  = 0;
            foreach ($mapelList as $mp) {
                $val    = $nilaiMap[$s['id']][$mp['id']] ?? '';
                $row[]  = $val;
                if ($val !== '') { $total += $val; $count++; }
            }
            $row[] = $count > 0 ? round($total / $count, 2) : '';
            fputcsv($out, $row);
        }

        fclose($out);
        exit;
    }

} // end class NilaiController
