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

/**
 * Controller Siswa
 */
class SiswaController {
    private $model;
    private $kelasModel;
    private $perPage = 15;

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

    public function index() {
        $search   = sanitize($_GET['search'] ?? '');
        $kelasId  = (int)($_GET['kelas_id'] ?? 0);
        $status   = sanitize($_GET['status'] ?? '');
        $curPage  = max(1, (int)($_GET['p'] ?? 1));
        $offset   = ($curPage - 1) * $this->perPage;

        $siswa  = $this->model->getAll($search, $kelasId ?: '', $status, $this->perPage, $offset);
        $total  = $this->model->countAll($search, $kelasId ?: '', $status);
        $kelasList = $this->kelasModel->getAllSimple();

        $baseUrl = BASE_URL . '/index.php?page=siswa&search=' . urlencode($search)
                 . '&kelas_id=' . $kelasId . '&status=' . urlencode($status);
        $pagination = paginate($total, $this->perPage, $curPage, $baseUrl);

        $pageTitle = 'Data Siswa';
        $flash = getFlash();
        include __DIR__ . '/../views/siswa/index.php';
    }

    public function tambah() {
        $kelasList = $this->kelasModel->getAllSimple();
        $errors = [];
        $data = [];

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            if (!validateCSRF($_POST['csrf_token'] ?? '')) {
                $errors[] = 'Token tidak valid.';
            } else {
                $data = $this->collectFormData();
                $errors = $this->validateData($data);

                if (empty($errors)) {
                    // Handle foto upload
                    $data['foto'] = null;
                    if (!empty($_FILES['foto']['name'])) {
                        $foto = uploadFile($_FILES['foto'], 'siswa');
                        if ($foto) $data['foto'] = $foto;
                    }

                    $siswaId = $this->model->insert($data);

                    if ($siswaId) {
                        // Alamat
                        $this->model->upsertAlamat($siswaId, $this->collectAlamatData());
                        // Orang tua
                        $this->model->upsertOrangTua($siswaId, $this->collectOrangTuaData());
                        // Wali
                        $this->model->upsertWali($siswaId, $this->collectWaliData());

                        setFlash('success', 'Data siswa berhasil ditambahkan.');
                        redirect(BASE_URL . '/index.php?page=siswa');
                    } else {
                        $errors[] = 'Gagal menyimpan data.';
                    }
                }
            }
        }

        $pageTitle = 'Tambah Siswa';
        $csrfToken = generateCSRF();
        include __DIR__ . '/../views/siswa/form.php';
    }

    public function edit() {
        $id = (int)($_GET['id'] ?? 0);
        if (!$id) { redirect(BASE_URL . '/index.php?page=siswa'); }

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

        $alamat   = $this->model->getAlamat($id) ?? [];
        $orangTua = $this->model->getOrangTua($id) ?? [];
        $wali     = $this->model->getWali($id) ?? [];
        $kelasList = $this->kelasModel->getAllSimple();
        $errors = [];

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            if (!validateCSRF($_POST['csrf_token'] ?? '')) {
                $errors[] = 'Token tidak valid.';
            } else {
                $data = $this->collectFormData();
                $errors = $this->validateData($data);

                if (empty($errors)) {
                    // Handle foto
                    if (!empty($_FILES['foto']['name'])) {
                        $foto = uploadFile($_FILES['foto'], 'siswa');
                        if ($foto) {
                            // Delete old foto
                            if (!empty($siswa['foto'])) {
                                @unlink(UPLOAD_PATH . $siswa['foto']);
                            }
                            $this->model->updateFoto($id, $foto);
                        }
                    }

                    $this->model->update($id, $data);
                    $this->model->upsertAlamat($id, $this->collectAlamatData());
                    $this->model->upsertOrangTua($id, $this->collectOrangTuaData());
                    $this->model->upsertWali($id, $this->collectWaliData());

                    setFlash('success', 'Data siswa berhasil diperbarui.');
                    redirect(BASE_URL . '/index.php?page=siswa');
                }
            }
        }

        $pageTitle = 'Edit Siswa';
        $csrfToken = generateCSRF();
        $isEdit = true;
        include __DIR__ . '/../views/siswa/form.php';
    }

    public function hapus() {
        $id = (int)($_GET['id'] ?? 0);
        if (!$id) { redirect(BASE_URL . '/index.php?page=siswa'); }

        if (!validateCSRF($_GET['csrf'] ?? '')) {
            setFlash('danger', 'Token tidak valid.');
            redirect(BASE_URL . '/index.php?page=siswa');
        }

        $siswa = $this->model->getById($id);
        if ($siswa) {
            // Delete foto
            if (!empty($siswa['foto'])) {
                @unlink(UPLOAD_PATH . $siswa['foto']);
            }
            $this->model->delete($id);
            setFlash('success', 'Data siswa berhasil dihapus.');
        } else {
            setFlash('danger', 'Data tidak ditemukan.');
        }
        redirect(BASE_URL . '/index.php?page=siswa');
    }

    public function detail() {
        $id = (int)($_GET['id'] ?? 0);
        if (!$id) { redirect(BASE_URL . '/index.php?page=siswa'); }

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

        $alamat   = $this->model->getAlamat($id) ?? [];
        $orangTua = $this->model->getOrangTua($id) ?? [];
        $wali     = $this->model->getWali($id) ?? [];

        // Rekap nilai semua semester (tanpa filter tahun/semester)
        require_once __DIR__ . '/../models/NilaiModel.php';
        $nilaiModel = new NilaiModel();
        $nilaiSiswa = $nilaiModel->getRekapNilaiSiswa($id);

        $pageTitle = 'Detail Siswa - ' . e($siswa['nama']);
        include __DIR__ . '/../views/siswa/detail.php';
    }

    public function import() {
        $pageTitle = 'Import Siswa';
        $flash     = getFlash();
        $errors    = [];
        $imported  = 0;
        $skipped   = 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 {
                $file = $_FILES['file'];
                $ext  = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));

                if ($ext !== 'csv') {
                    $errors[] = 'Hanya file CSV yang didukung. Simpan Excel sebagai CSV (UTF-8) terlebih dahulu.';
                } else {
                    // Baca file, deteksi BOM UTF-8
                    $content = file_get_contents($file['tmp_name']);
                    // Hapus BOM jika ada
                    $content = ltrim($content, "\xEF\xBB\xBF");
                    $tmpFile = tmpfile();
                    fwrite($tmpFile, $content);
                    rewind($tmpFile);

                    // Build kelas map: nama_kelas (lowercase) => id
                    $kelasList = $this->kelasModel->getAllSimple();
                    $kelasMap  = [];
                    foreach ($kelasList as $k) {
                        $kelasMap[strtolower(trim($k['nama_kelas']))] = $k['id'];
                    }

                    $header = fgetcsv($tmpFile); // skip baris header
                    $rowNum = 1;

                    while (($row = fgetcsv($tmpFile)) !== false) {
                        $rowNum++;
                        // Minimal kolom: No, NIS, NISN, NIK, Nama
                        if (count($row) < 5 || empty(trim($row[4]))) {
                            $skipped++;
                            continue;
                        }

                        // Kolom 0-13: Data Pokok Siswa
                        // 0=No, 1=NIS, 2=NISN, 3=NIK, 4=Nama, 5=JK, 6=Kelas,
                        // 7=Agama, 8=Tempat Lahir, 9=Tgl Lahir, 10=Anak Ke,
                        // 11=Tgl Masuk, 12=Asal Sekolah, 13=Status
                        $namaKelas = strtolower(trim($row[6] ?? ''));
                        $kelasId   = $kelasMap[$namaKelas] ?? null;

                        // Validasi status — hanya nilai yang diizinkan
                        $statusInput = trim($row[13] ?? 'Aktif');
                        $statusValid = ['Aktif','Gaib','Tidak Aktif','Lulus','Pindah','Keluar'];
                        $statusSiswa = in_array($statusInput, $statusValid) ? $statusInput : 'Aktif';

                        $siswaData = [
                            'no'            => !empty($row[0]) ? (int)$row[0] : null,
                            'nis'           => trim($row[1] ?? ''),
                            'nisn'          => trim($row[2] ?? ''),
                            'nik'           => trim($row[3] ?? ''),
                            'nama'          => trim($row[4] ?? ''),
                            'jenis_kelamin' => trim($row[5] ?? 'Laki-laki'),
                            'kelas_id'      => $kelasId,
                            'agama'         => trim($row[7] ?? 'Islam'),
                            'tempat_lahir'  => trim($row[8] ?? ''),
                            'tanggal_lahir' => !empty($row[9]) ? trim($row[9]) : null,
                            'anak_ke'       => !empty($row[10]) ? (int)$row[10] : null,
                            'tgl_masuk'     => !empty($row[11]) ? trim($row[11]) : null,
                            'asal_sekolah'  => trim($row[12] ?? ''),
                            'status'        => $statusSiswa,
                            'foto'          => null,
                        ];

                        $siswaId = $this->model->insert($siswaData);

                        if ($siswaId) {
                            // Kolom 14-19: Alamat
                            $alamatData = [
                                'alamat'    => trim($row[14] ?? ''),
                                'rt'        => trim($row[15] ?? ''),
                                'rw'        => trim($row[16] ?? ''),
                                'dusun'     => trim($row[17] ?? ''),
                                'kelurahan' => trim($row[18] ?? ''),
                                'kecamatan' => trim($row[19] ?? ''),
                                'kabupaten' => '',
                                'provinsi'  => '',
                                'kode_pos'  => '',
                            ];
                            if (!empty($alamatData['alamat']) || !empty($alamatData['kelurahan'])) {
                                $this->model->upsertAlamat($siswaId, $alamatData);
                            }

                            // Kolom 20-23: Orang Tua (tanpa alamat_orang_tua)
                            $ortuData = [
                                'nama_ayah'        => trim($row[20] ?? ''),
                                'nama_ibu'         => trim($row[21] ?? ''),
                                'pekerjaan_ayah'   => trim($row[22] ?? ''),
                                'pekerjaan_ibu'    => trim($row[23] ?? ''),
                                'alamat_orang_tua' => '',
                                'no_hp_ayah'       => '',
                                'no_hp_ibu'        => '',
                                'penghasilan'      => '',
                            ];
                            if (!empty($ortuData['nama_ayah']) || !empty($ortuData['nama_ibu'])) {
                                $this->model->upsertOrangTua($siswaId, $ortuData);
                            }

                            // Kolom 24-26: Wali
                            $waliData = [
                                'nama_wali'      => trim($row[24] ?? ''),
                                'alamat_wali'    => trim($row[25] ?? ''),
                                'pekerjaan_wali' => trim($row[26] ?? ''),
                                'no_hp_wali'     => '',
                                'hubungan'       => '',
                            ];
                            if (!empty($waliData['nama_wali'])) {
                                $this->model->upsertWali($siswaId, $waliData);
                            }

                            $imported++;
                        } else {
                            $skipped++;
                        }
                    }

                    fclose($tmpFile);

                    $msg = "$imported data siswa berhasil diimport.";
                    if ($skipped > 0) $msg .= " $skipped baris dilewati.";
                    setFlash('success', $msg);
                    redirect(BASE_URL . '/index.php?page=siswa');
                }
            }
        }

        $csrfToken = generateCSRF();
        include __DIR__ . '/../views/siswa/import.php';
    }

    public function export() {
        $kelasId = (int)($_GET['kelas_id'] ?? 0);
        $status  = sanitize($_GET['status'] ?? '');

        $data = $this->model->getAllForExport($kelasId ?: '', $status);

        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="data_siswa_' . date('Ymd_His') . '.csv"');

        $output = fopen('php://output', 'w');
        // BOM agar Excel baca UTF-8 dengan benar
        fputs($output, "\xEF\xBB\xBF");

        // Header kolom — urutan sama dengan template import
        fputcsv($output, [
            'No', 'NIS', 'NISN', 'NIK', 'Nama', 'Jenis Kelamin', 'Kelas',
            'Agama', 'Tempat Lahir', 'Tanggal Lahir', 'Anak Ke',
            'Tgl Masuk', 'Asal Sekolah', 'Status',
            // Alamat
            'Alamat', 'RT', 'RW', 'Dusun', 'Kelurahan', 'Kecamatan',
            // Orang Tua (tanpa alamat)
            'Nama Ayah', 'Nama Ibu', 'Pekerjaan Ayah', 'Pekerjaan Ibu',
            // Wali
            'Nama Wali', 'Alamat Wali', 'Pekerjaan Wali',
        ]);

        $no = 1;
        foreach ($data as $row) {
            fputcsv($output, [
                $no++,
                $row['nis']           ?? '',
                $row['nisn']          ?? '',
                $row['nik']           ?? '',
                $row['nama']          ?? '',
                $row['jenis_kelamin'] ?? '',
                $row['nama_kelas']    ?? '',
                $row['agama']         ?? '',
                $row['tempat_lahir']  ?? '',
                $row['tanggal_lahir'] ?? '',
                $row['anak_ke']       ?? '',
                $row['tgl_masuk']     ?? '',
                $row['asal_sekolah']  ?? '',
                $row['status']        ?? '',
                // Alamat
                $row['alamat']        ?? '',
                $row['rt']            ?? '',
                $row['rw']            ?? '',
                $row['dusun']         ?? '',
                $row['kelurahan']     ?? '',
                $row['kecamatan']     ?? '',
                // Orang Tua (tanpa alamat)
                $row['nama_ayah']      ?? '',
                $row['nama_ibu']       ?? '',
                $row['pekerjaan_ayah'] ?? '',
                $row['pekerjaan_ibu']  ?? '',
                // Wali
                $row['nama_wali']      ?? '',
                $row['alamat_wali']    ?? '',
                $row['pekerjaan_wali'] ?? '',
            ]);
        }
        fclose($output);
        exit;
    }

    private function collectFormData() {
        return [
            'no'            => (int)($_POST['no'] ?? 0) ?: null,
            'nis'           => sanitize($_POST['nis'] ?? ''),
            'nisn'          => sanitize($_POST['nisn'] ?? ''),
            'nik'           => sanitize($_POST['nik'] ?? ''),
            'nama'          => sanitize($_POST['nama'] ?? ''),
            'jenis_kelamin' => sanitize($_POST['jenis_kelamin'] ?? ''),
            'kelas_id'      => (int)($_POST['kelas_id'] ?? 0) ?: null,
            'agama'         => sanitize($_POST['agama'] ?? ''),
            'tempat_lahir'  => sanitize($_POST['tempat_lahir'] ?? ''),
            'tanggal_lahir' => sanitize($_POST['tanggal_lahir'] ?? '') ?: null,
            'anak_ke'       => (int)($_POST['anak_ke'] ?? 0) ?: null,
            'tgl_masuk'     => sanitize($_POST['tgl_masuk'] ?? '') ?: null,
            'asal_sekolah'  => sanitize($_POST['asal_sekolah'] ?? ''),
            'status'        => sanitize($_POST['status'] ?? 'Aktif'),
        ];
    }

    private function collectAlamatData() {
        return [
            'alamat'     => sanitize($_POST['alamat'] ?? ''),
            'rt'         => sanitize($_POST['rt'] ?? ''),
            'rw'         => sanitize($_POST['rw'] ?? ''),
            'dusun'      => sanitize($_POST['dusun'] ?? ''),
            'kelurahan'  => sanitize($_POST['kelurahan'] ?? ''),
            'kecamatan'  => sanitize($_POST['kecamatan'] ?? ''),
            'kabupaten'  => sanitize($_POST['kabupaten'] ?? ''),
            'provinsi'   => sanitize($_POST['provinsi'] ?? ''),
            'kode_pos'   => sanitize($_POST['kode_pos'] ?? ''),
        ];
    }

    private function collectOrangTuaData() {
        return [
            'nama_ayah'       => sanitize($_POST['nama_ayah'] ?? ''),
            'nama_ibu'        => sanitize($_POST['nama_ibu'] ?? ''),
            'pekerjaan_ayah'  => sanitize($_POST['pekerjaan_ayah'] ?? ''),
            'pekerjaan_ibu'   => sanitize($_POST['pekerjaan_ibu'] ?? ''),
            'alamat_orang_tua'=> sanitize($_POST['alamat_orang_tua'] ?? ''),
            'no_hp_ayah'      => sanitize($_POST['no_hp_ayah'] ?? ''),
            'no_hp_ibu'       => sanitize($_POST['no_hp_ibu'] ?? ''),
            'penghasilan'     => sanitize($_POST['penghasilan'] ?? ''),
        ];
    }

    private function collectWaliData() {
        return [
            'nama_wali'      => sanitize($_POST['nama_wali'] ?? ''),
            'alamat_wali'    => sanitize($_POST['alamat_wali'] ?? ''),
            'pekerjaan_wali' => sanitize($_POST['pekerjaan_wali'] ?? ''),
            'no_hp_wali'     => sanitize($_POST['no_hp_wali'] ?? ''),
            'hubungan'       => sanitize($_POST['hubungan'] ?? ''),
        ];
    }

    public function suratPindah() {
        $id = (int)($_GET['id'] ?? 0);
        if (!$id) redirect(BASE_URL . '/index.php?page=siswa');

        $siswa = $this->model->getById($id);
        if (!$siswa || !in_array($siswa['status'], ['Pindah', 'Keluar'])) {
            setFlash('danger', 'Surat hanya tersedia untuk siswa dengan status Pindah atau Keluar.');
            redirect(BASE_URL . '/index.php?page=siswa');
        }

        $orangTua = $this->model->getOrangTua($id) ?? [];
        $wali     = $this->model->getWali($id) ?? [];

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

        // Nomor surat otomatis: format 001/KODE/SK/BULAN_ROMAWI/TAHUN
        $bulanRomawi = ['','I','II','III','IV','V','VI','VII','VIII','IX','X','XI','XII'];
        $bulan       = (int)date('n');
        $tahun       = date('Y');

        // Hitung nomor urut dari jumlah siswa pindah/keluar yang ada
        $countRow  = query_fetch_assoc($db, "SELECT COUNT(*) as total FROM siswa WHERE status IN ('Pindah','Keluar')") ?? ['total' => 0];
        $nomorUrut = str_pad((int)($countRow['total'] ?? 1), 3, '0', STR_PAD_LEFT);

        $kodeSekolah = !empty($sekolah['npsn']) ? $sekolah['npsn'] : 'SKL';
        $nomorSurat  = $nomorUrut . '/' . $kodeSekolah . '/SK/' . $bulanRomawi[$bulan] . '/' . $tahun;

        // Nama orang tua/wali untuk surat
        $namaOrtu = '';
        if (!empty($orangTua['nama_ayah'])) {
            $namaOrtu = $orangTua['nama_ayah'];
        } elseif (!empty($orangTua['nama_ibu'])) {
            $namaOrtu = $orangTua['nama_ibu'];
        } elseif (!empty($wali['nama_wali'])) {
            $namaOrtu = $wali['nama_wali'];
        }

        $pageTitle = 'Surat Keterangan Pindah/Keluar';
        include __DIR__ . '/../views/siswa/surat_pindah.php';
    }

    private function validateData($data) {
        $errors = [];
        if (empty($data['nama'])) $errors[] = 'Nama siswa wajib diisi.';
        if (empty($data['jenis_kelamin'])) $errors[] = 'Jenis kelamin wajib dipilih.';
        return $errors;
    }
}
