<?php

namespace App\Controllers;

class Rekap extends BaseController
{
    protected $db;

    public function __construct()
    {
        $this->db = \Config\Database::connect();
        // makassar
        date_default_timezone_set('Asia/Jakarta');
    }

    public function index()
    {
        $db = \Config\Database::connect();
        $request = \Config\Services::request();

        $level = session()->get('level');
        $id_opd_admin = session()->get('id_opd');

        $bulan = $request->getGet('bulan') ?? date('m');
        $tahun = $request->getGet('tahun') ?? date('Y');

        $id_opd = $request->getGet('id_opd');
        if (!in_array($level, ['Superadmin', 'kabupaten'])) {
            $id_opd = $id_opd_admin;
        }

        $list_opd = $db->table('opd')->orderBy('nama_opd', 'ASC')->get()->getResultArray();

        // Ambil Data Libur
        $libur_db = $db->table('hari_libur')
            ->where("MONTH(tanggal)", $bulan)->where("YEAR(tanggal)", $tahun)
            ->get()->getResultArray();
        $libur_nasional = [];
        foreach ($libur_db as $l) $libur_nasional[$l['tanggal']] = $l['keterangan'];

        // Ambil Jadwal Kerja
        $jadwal_db = $db->table('jam_kerja_detail')->get()->getResultArray();
        $jadwal_kerja = [];
        foreach ($jadwal_db as $j) $jadwal_kerja[$j['id_jam_kerja']][$j['hari']] = true;

        $hari_indo_map = [
            'Sun' => 'Minggu', 'Mon' => 'Senin', 'Tue' => 'Selasa', 'Wed' => 'Rabu',
            'Thu' => 'Kamis', 'Fri' => 'Jumat', 'Sat' => 'Sabtu'
        ];

        $rekap_final = [];
        $list_tanggal = [];

        if ($id_opd) {
            $jumlah_hari = date('t', mktime(0, 0, 0, $bulan, 1, $tahun));
            for ($d = 1; $d <= $jumlah_hari; $d++) {
                $list_tanggal[] = date('Y-m-d', mktime(0, 0, 0, $bulan, $d, $tahun));
            }

            // --- MODIFIKASI: LOGIKA FILTER TERPISAH (ESELON II, III, IV) ---
            $builder_pegawai = $db->table('pegawai')
                ->select('pegawai.*, opd.nama_opd')
                ->join('opd', 'pegawai.id_opd = opd.id_opd', 'left');

            if ($id_opd == 'rekap_eselon_2') {
                $builder_pegawai->whereIn('eselon', ['II.a', 'II.b']);
            } elseif ($id_opd == 'rekap_eselon_3') {
                $builder_pegawai->whereIn('eselon', ['III.a', 'III.b']);
            } elseif ($id_opd == 'rekap_eselon_4') {
                $builder_pegawai->whereIn('eselon', ['IV.a', 'IV.b']);
            } else {
                // Jika memilih OPD tertentu
                $builder_pegawai->where('pegawai.id_opd', $id_opd);
            }

            $pegawai = $builder_pegawai->orderBy("CASE 
                    WHEN TRIM(eselon) = 'II.a' THEN 1 WHEN TRIM(eselon) = 'II.b' THEN 2
                    WHEN TRIM(eselon) = 'III.a' THEN 3 WHEN TRIM(eselon) = 'III.b' THEN 4
                    WHEN TRIM(eselon) = 'IV.a' THEN 5 WHEN TRIM(eselon) = 'IV.b' THEN 6
                    ELSE 7 END", "ASC", false)
                ->orderBy('nama_lengkap', 'ASC')
                ->get()->getResultArray();

            $ids_pegawai = array_column($pegawai, 'id_pegawai');
            $nips_pegawai = array_column($pegawai, 'nip');

            if (!empty($ids_pegawai)) {
                // Ambil Data Cuti massal
                $cuti_raw = $db->table('pengajuan_cuti')
                    ->select('pengajuan_cuti.*, master_cuti.nama_cuti')
                    ->join('master_cuti', 'master_cuti.id_cuti = pengajuan_cuti.cuti_id')
                    ->whereIn('pegawai_id', $ids_pegawai)
                    ->where('status', 'disetujui')
                    ->where("((MONTH(tgl_mulai) = $bulan AND YEAR(tgl_mulai) = $tahun) OR (MONTH(tgl_selesai) = $bulan AND YEAR(tgl_selesai) = $tahun))")
                    ->get()->getResultArray();

                $map_cuti = [];
                foreach ($cuti_raw as $c) {
                    $start = new \DateTime($c['tgl_mulai']);
                    $end = new \DateTime($c['tgl_selesai']);
                    $end->modify('+1 day');
                    $period = new \DatePeriod($start, new \DateInterval('P1D'), $end);
                    foreach ($period as $date) {
                        $map_cuti[$c['pegawai_id']][$date->format('Y-m-d')] = $c['nama_cuti'];
                    }
                }

                // Ambil Data Presensi massal
                $presensi_raw = $db->table('presensi')
                    ->whereIn('nip', $nips_pegawai)
                    ->where("MONTH(presensi.tanggal)", $bulan)
                    ->where("YEAR(presensi.tanggal)", $tahun)
                    ->get()->getResultArray();

                $data_presensi = [];
                foreach ($presensi_raw as $p) $data_presensi[$p['nip']][$p['tanggal']] = $p;

                foreach ($pegawai as $pgw) {
                    $row = [
                        'nama'    => $pgw['nama_lengkap'],
                        'nip'     => $pgw['nip'],
                        'jabatan' => $pgw['jabatan'] ?? '-',
                        'nama_opd'=> $pgw['nama_opd'],
                        'harian'  => []
                    ];

                    $id_jk = $pgw['id_jam_kerja'] ?? 1;

                    foreach ($list_tanggal as $tgl) {
                        $day_eng = date('D', strtotime($tgl));
                        $nama_hari = $hari_indo_map[$day_eng];

                        $data_hari = [
                            'tanggal' => $tgl, 'hari' => $nama_hari,
                            'masuk' => '-', 'siang' => '-', 'pulang' => '-',
                            'status' => '', 'bg' => '', 'telat' => 0, 'cepat' => 0
                        ];

                        if (isset($data_presensi[$pgw['nip']][$tgl])) {
                            $p = $data_presensi[$pgw['nip']][$tgl];
                            $data_hari['masuk']  = $p['jam_masuk_aktual'] ? date('H:i', strtotime($p['jam_masuk_aktual'])) : '-';
                            $data_hari['siang']  = $p['jam_siang'] ? date('H:i', strtotime($p['jam_siang'])) : '-';
                            $data_hari['pulang'] = $p['jam_pulang_aktual'] ? date('H:i', strtotime($p['jam_pulang_aktual'])) : '-';
                            $data_hari['telat']  = intval($p['menit_keterlambatan']);

                            // =========================================================================
                            // MODIFIKASI KATEGORI WARNA STATUS (SANGAT BAIK, BAIK, TERLAMBAT, DLL)
                            // =========================================================================
                            if ($p['kategori'] == 'Hadir' || strpos($p['kategori'], 'Apel') !== false) {
                                $jam = $p['jam_masuk_aktual'];
                                
                                if ($jam && $jam <= '07:30:00') {
                                    $data_hari['status'] = '<span class="badge w-100 text-start shadow-sm" style="background-color: #155724; color: #ffffff;">Sangat Baik / Istimewa</span>';
                                } elseif ($jam && $jam <= '07:45:00') {
                                    $data_hari['status'] = '<span class="badge w-100 text-start shadow-sm" style="background-color: #28a745; color: #ffffff;">Baik</span>';
                                } elseif ($jam && $jam <= '08:15:00') {
                                    $data_hari['status'] = '<span class="badge w-100 text-start shadow-sm" style="background-color: #8ce196; color: #000000;">Cukup Baik</span>';
                                } elseif ($jam && $jam <= '09:00:00') {
                                    $data_hari['status'] = '<span class="badge w-100 text-start shadow-sm" style="background-color: #fff3cd; color: #000000;">Terlambat</span>';
                                } elseif ($jam && $jam <= '10:00:00') {
                                    $data_hari['status'] = '<span class="badge w-100 text-start shadow-sm" style="background-color: #ffc107; color: #000000;">Pembinaan</span>';
                                } elseif ($jam) {
                                    $data_hari['status'] = '<span class="badge w-100 text-start shadow-sm" style="background-color: #dc3545; color: #ffffff;">Teguran</span>';
                                } else {
                                    $data_hari['status'] = '<span class="badge w-100 text-start bg-secondary">Hadir Tanpa Jam</span>';
                                }
                                $data_hari['bg'] = ''; // Background dikosongkan karena warna sudah dihandle oleh badge HTML di atas
                            } else {
                                // Jika statusnya Izin, Sakit, atau Dinas Luar
                                $data_hari['status'] = '<span class="badge bg-info text-dark border w-100 text-start">' . $p['kategori'] . '</span>';
                                $data_hari['bg'] = '';
                            }
                            // =========================================================================

                        }
                        elseif (isset($libur_nasional[$tgl])) {
                            $data_hari['status'] = 'Libur: ' . $libur_nasional[$tgl];
                            $data_hari['bg'] = 'text-danger small';
                        } elseif ($day_eng == 'Sun' || $day_eng == 'Sat') {
                            $data_hari['status'] = 'Libur Akhir Pekan';
                            $data_hari['bg'] = 'text-muted small';
                        }
                        elseif (isset($map_cuti[$pgw['id_pegawai']][$tgl])) {
                            $data_hari['status'] = 'CUTI: ' . $map_cuti[$pgw['id_pegawai']][$tgl];
                            $data_hari['bg'] = 'text-primary fw-bold';
                        }
                        elseif (!isset($jadwal_kerja[$id_jk][$nama_hari])) {
                            $data_hari['status'] = 'Bukan Hari Kerja';
                            $data_hari['bg'] = 'text-secondary small';
                        } else {
                            $data_hari['status'] = '<span class="badge w-100 text-start" style="background-color: transparent; border: 1px solid #dc3545; color: #dc3545;">Tanpa Keterangan (Alpha)</span>';
                            $data_hari['bg'] = '';
                        }
                        $row['harian'][] = $data_hari;
                    }
                    $rekap_final[] = $row;
                }
            }
        }

        $data = [
            'title'        => 'Rekapitulasi Presensi',
            'list_opd'     => $list_opd,
            'rekap'        => $rekap_final,
            'bulan'        => $bulan,
            'tahun'        => $tahun,
            'selected_opd' => $id_opd
        ];

        return view('admin/rekap_presensi', $data);
    }

    private function get_nama_hari($day)
    {
        $days = ['Sun' => 'Minggu', 'Mon' => 'Senin', 'Tue' => 'Selasa', 'Wed' => 'Rabu', 'Thu' => 'Kamis', 'Fri' => 'Jumat', 'Sat' => 'Sabtu'];
        return $days[$day];
    }

    public function keterlambatan()
    {
        $db      = \Config\Database::connect();
        $request = \Config\Services::request();
        $session = session();

        $bulan   = $request->getGet('bulan') ?? date('m');
        $tahun   = $request->getGet('tahun') ?? date('Y');
        $id_opd  = $request->getGet('id_opd');

        if ($session->get('level') == 'opd') {
            $id_opd = $session->get('id_opd');
        }

        // --- 1. HITUNG HARI KERJA EFEKTIF ---
        $today = date('Y-m-d');
        $last_day_of_month = date('Y-m-t', strtotime("$tahun-$bulan-01"));
        $endDate = (date('m') == $bulan && date('Y') == $tahun) ? $today : $last_day_of_month;
        
        $libur_raw = $db->table('hari_libur')->where("MONTH(tanggal)", $bulan)->where("YEAR(tanggal)", $tahun)->get()->getResultArray();
        $list_libur = array_column($libur_raw, 'tanggal');

        $hari_kerja_efektif = 0;
        $start_date = new \DateTime("$tahun-$bulan-01");
        $end_date   = new \DateTime($endDate);
        $end_date->modify('+1 day'); 
        foreach (new \DatePeriod($start_date, new \DateInterval('P1D'), $end_date) as $date) {
            if ($date->format('N') < 6 && !in_array($date->format('Y-m-d'), $list_libur)) $hari_kerja_efektif++;
        }

        // --- 2. QUERY REKAP DISIPLIN ---
        $builder = $db->table('pegawai p');
        $builder->select("p.id_pegawai, p.nama_lengkap, p.nip, p.level_jabatan, p.eselon, p.jabatan, o.nama_opd,
            COUNT(CASE WHEN pr.kategori = 'Hadir' THEN 1 END) as total_hadir, 
            
            /* Keterlambatan */
            SUM(CASE WHEN pr.status_masuk = 'Terlambat' THEN 1 ELSE 0 END) as frekuensi_telat,
            SUM(COALESCE(pr.menit_keterlambatan, 0)) as total_menit_telat,
            
            /* Pulang Cepat (PC) */
            SUM(CASE WHEN pr.jam_pulang_aktual < pr.jam_pulang_seharusnya THEN 1 ELSE 0 END) as frekuensi_pc,
            SUM(CASE WHEN pr.jam_pulang_aktual < pr.jam_pulang_seharusnya 
                    THEN TIMESTAMPDIFF(MINUTE, pr.jam_pulang_aktual, pr.jam_pulang_seharusnya) 
                    ELSE 0 END) as total_menit_pc,

            SUM(CASE WHEN pr.kategori IN ('Sakit/Izin', 'Sakit', 'Izin') THEN 1 ELSE 0 END) as total_izin_sakit,
            SUM(CASE WHEN pr.kategori = 'Tugas Luar' THEN 1 ELSE 0 END) as total_dl,

            /* Hitung Cuti */
            (SELECT COUNT(*) FROM pengajuan_cuti c 
            WHERE c.pegawai_id = p.id_pegawai 
            AND c.status = 'disetujui' 
            AND ((MONTH(c.tgl_mulai) = ".$db->escape($bulan)." AND YEAR(c.tgl_mulai) = ".$db->escape($tahun).") 
            OR (MONTH(c.tgl_selesai) = ".$db->escape($bulan)." AND YEAR(c.tgl_selesai) = ".$db->escape($tahun)."))) as total_cuti", false); 

        $builder->join('presensi pr', 'p.nip = pr.nip AND MONTH(pr.tanggal) = ' . $db->escape($bulan) . ' AND YEAR(pr.tanggal) = ' . $db->escape($tahun), 'left');
        $builder->join('opd o', 'p.id_opd = o.id_opd', 'left');

        if ($id_opd == 'rekap_eselon_2') {
            $builder->whereIn('p.eselon', ['II.a', 'II.b']);
        } elseif ($id_opd == 'rekap_eselon_3') {
            $builder->whereIn('p.eselon', ['III.a', 'III.b']);
        } elseif ($id_opd == 'rekap_eselon_4') {
            $builder->whereIn('p.eselon', ['IV.a', 'IV.b']);
        } else {
            $builder->where('p.id_opd', $id_opd);
        }

        $builder->groupBy('p.nip');

        $builder->orderBy("CASE 
            WHEN TRIM(p.eselon) = 'II.a' THEN 1 WHEN TRIM(p.eselon) = 'II.b' THEN 2
            WHEN TRIM(p.eselon) = 'III.a' THEN 3 WHEN TRIM(p.eselon) = 'III.b' THEN 4
            WHEN TRIM(p.eselon) = 'IV.a' THEN 5 WHEN TRIM(p.eselon) = 'IV.b' THEN 6
            WHEN p.level_jabatan LIKE '%Fungsional%' THEN 7
            WHEN p.level_jabatan LIKE '%Staf%' OR TRIM(p.eselon) = 'Non Eselon' THEN 8
            ELSE 9 END", "ASC", false);
        
        $pegawai_raw = $builder->get()->getResultArray();

        $data_final = [];
        foreach ($pegawai_raw as $row) {
            $total_absen_sah = $row['total_hadir'] + $row['total_izin_sakit'] + $row['total_dl'] + $row['total_cuti'];
            $row['total_alpa'] = max(0, $hari_kerja_efektif - $total_absen_sah);
            $data_final[] = $row;
        }

        $data = [
            'title'        => 'Rekap Disiplin Kerja',
            'pegawai'      => $data_final,
            'list_opd'     => $db->table('opd')->orderBy('nama_opd', 'ASC')->get()->getResultArray(),
            'bulan'        => $bulan, 
            'tahun'        => $tahun, 
            'selected_opd' => $id_opd,
            'hari_kerja'   => $hari_kerja_efektif
        ];

        return view('rekap/keterlambatan', $data);
    }

    public function tpp()
    {
        $db = \Config\Database::connect();
        $level = session()->get('level');
        $id_opd_admin = session()->get('id_opd');
        $request = \Config\Services::request();

        // 1. Ambil Filter Bulan, Tahun, dan OPD
        $bulan = $request->getGet('bulan') ?? date('m');
        $tahun = $request->getGet('tahun') ?? date('Y');
        $id_opd = $request->getGet('id_opd');

        // Keamanan Hak Akses
        if (!in_array($level, ['Superadmin', 'kabupaten'])) {
            $id_opd = $id_opd_admin;
        }

        $data_pegawai = [];
        $nama_opd = "Semua Instansi";

        if ($id_opd) {
            $opd_info = $db->table('opd')->where('id_opd', $id_opd)->get()->getRow();
            $nama_opd = $opd_info->nama_opd ?? "-";

            // 2. AMBIL DATA CUTI (EAGER LOADING)
            // Cuti diambil dari tabel pengajuan_cuti yang sudah disetujui
            $cuti_raw = $db->table('pengajuan_cuti')
                ->where('status', 'disetujui')
                ->where("((MONTH(tgl_mulai) = $bulan AND YEAR(tgl_mulai) = $tahun) OR (MONTH(tgl_selesai) = $bulan AND YEAR(tgl_selesai) = $tahun))")
                ->get()->getResultArray();

            $map_cuti = [];
            foreach ($cuti_raw as $c) {
                $start = new \DateTime($c['tgl_mulai']);
                $end = new \DateTime($c['tgl_selesai']);
                $end->modify('+1 day');
                $period = new \DatePeriod($start, new \DateInterval('P1D'), $end);
                foreach ($period as $date) {
                    if ($date->format('m') == $bulan && $date->format('Y') == $tahun) {
                        $map_cuti[$c['pegawai_id']][] = $date->format('Y-m-d');
                    }
                }
            }

            // 3. AMBIL DATA PEGAWAI DENGAN URUTAN HIERARKI KETAT
            $pegawai = $db->table('pegawai p')
                ->where('p.id_opd', $id_opd)
                ->orderBy("CASE 
                    WHEN TRIM(eselon) = 'II.a' THEN 1
                    WHEN TRIM(eselon) = 'II.b' THEN 2
                    WHEN TRIM(eselon) = 'III.a' THEN 3
                    WHEN TRIM(eselon) = 'III.b' THEN 4
                    WHEN TRIM(eselon) = 'IV.a' THEN 5
                    WHEN TRIM(eselon) = 'IV.b' THEN 6
                    WHEN level_jabatan LIKE '%Fungsional%' THEN 7
                    WHEN level_jabatan LIKE '%Staf%' OR TRIM(eselon) = 'Non Eselon' THEN 8
                    ELSE 9 END", "ASC", false)
                ->orderBy('nama_lengkap', 'ASC')
                ->get()->getResultArray();

            // 4. LOOPING PER PEGAWAI UNTUK HITUNG REKAP & POTONGAN
            foreach ($pegawai as $pgw) {
                $logs = $db->table('presensi')
                    ->where('nip', $pgw['nip'])
                    ->where('MONTH(tanggal)', $bulan)
                    ->where('YEAR(tanggal)', $tahun)
                    ->get()->getResultArray();

                $res = [
                    'nama'    => $pgw['nama_lengkap'],
                    'nip'     => $pgw['nip'],
                    'jab'     => $pgw['jabatan'],
                    'eselon'  => $pgw['eselon'],
                    'p1' => 0, 'p2' => 0, 'p3' => 0, 'p4' => 0, // Terlambat (Tb)
                    'pc1' => 0, 'pc2' => 0, 'pc3' => 0, 'pc4' => 0, // Pulang Cepat (PC)
                    'c' => 0,   // Cuti
                    'i' => 0,   // Izin / Sakit/Izin
                    'ish' => 0, // Izin Setengah Hari
                    'a' => 0,   // Alpa
                    's' => 0,   // Sakit (dengan surat)
                    'dl' => 0,  // Dinas Luar
                    'total_persen' => 0
                ];

                // Hitung Frekuensi Cuti dari Map
                if (isset($map_cuti[$pgw['id_pegawai']])) {
                    $res['c'] = count(array_unique($map_cuti[$pgw['id_pegawai']]));
                }

                foreach ($logs as $l) {
                    // A. Hitung Terlambat (Tb)
                    if ($l['status_masuk'] == 'Terlambat') {
                        $m = $l['menit_keterlambatan'];
                        if ($m >= 1 && $m <= 30) $res['p1']++;
                        elseif ($m >= 31 && $m <= 60) $res['p2']++;
                        elseif ($m >= 61 && $m <= 90) $res['p3']++;
                        elseif ($m > 90) $res['p4']++;
                    }

                    // B. Hitung Pulang Cepat (PC)
                    if ($l['jam_pulang_aktual'] && $l['jam_pulang_seharusnya']) {
                        if ($l['jam_pulang_aktual'] < $l['jam_pulang_seharusnya']) {
                            $selisih = strtotime($l['jam_pulang_seharusnya']) - strtotime($l['jam_pulang_aktual']);
                            $menit_pc = floor($selisih / 60);
                            if ($menit_pc >= 1 && $menit_pc <= 30) $res['pc1']++;
                            elseif ($menit_pc >= 31 && $menit_pc <= 60) $res['pc2']++;
                            elseif ($menit_pc >= 61 && $menit_pc <= 90) $res['pc3']++;
                            elseif ($menit_pc > 90) $res['pc4']++;
                        }
                    }

                    // C. Hitung Ketidakhadiran (Sesuai Data Database)
                    if (in_array($l['kategori'], ["Sakit/Izin", "Izin"])) {
                        $res['i']++;
                    } elseif ($l['kategori'] == 'Izin Setengah Hari') {
                        $res['ish']++;
                    } elseif ($l['kategori'] == 'Alpa') {
                        $res['a']++;
                    } elseif ($l['kategori'] == 'Sakit') {
                        $res['s']++;
                    } elseif (in_array($l['kategori'], ["Tugas Luar", "Dinas Luar"])) {
                        $res['dl']++;
                    }
                }

                // 5. RUMUS PERHITUNGAN PERSENTASE POTONGAN TPP
                $res['total_persen'] =
                    ($res['p1'] * 0.5) + ($res['p2'] * 1) + ($res['p3'] * 1.25) + ($res['p4'] * 1.5) + // Potongan Tb
                    ($res['pc1'] * 0.5) + ($res['pc2'] * 1) + ($res['pc3'] * 1.25) + ($res['pc4'] * 1.5) + // Potongan PC
                    ($res['i'] * 2) + ($res['ish'] * 1) + ($res['a'] * 5); // Potongan Izin & Alpa

                $data_pegawai[] = $res;
            }
        }

        // 6. Kirim ke View
        return view('admin/rekap_tpp', [
            'pegawai'      => $data_pegawai,
            'list_opd'     => $db->table('opd')->orderBy('nama_opd', 'ASC')->get()->getResultArray(),
            'bulan'        => $bulan,
            'tahun'        => $tahun,
            'selected_opd' => $id_opd,
            'nama_opd'     => $nama_opd
        ]);
    }

    public function manual()
    {
        $db = $this->db;
        $request = \Config\Services::request();
        $session = session();

        $level = $session->get('level');
        $id_opd_session = $session->get('id_opd');

        // Ambil Filter OPD dari Get (untuk Kabupaten/Superadmin)
        $id_opd_filter = $request->getGet('id_opd');

        // LOGIKA PROTEKSI LEVEL
        if ($level == 'opd') {
            $id_final_opd = $id_opd_session; // Admin OPD terkunci ke kantornya sendiri
        } else {
            $id_final_opd = $id_opd_filter; // Kabupaten bisa pilih OPD manapun
        }

        // Ambil List OPD untuk Dropdown (Hanya muncul jika level Kabupaten/Superadmin)
        $list_opd = $db->table('opd')->orderBy('nama_opd', 'ASC')->get()->getResultArray();

        // Ambil daftar pegawai berdasarkan OPD yang ditentukan
        $builder = $db->table('pegawai');
        if ($id_final_opd) {
            $builder->where('id_opd', $id_final_opd);
        }

        // Jika Superadmin/Kabupaten belum pilih OPD, jangan tampilkan pegawai dulu biar ringan
        if (!$id_final_opd && in_array($level, ['Superadmin', 'kabupaten'])) {
            $pegawai = [];
        } else {
            $pegawai = $builder->orderBy('nama_lengkap', 'ASC')->get()->getResultArray();
        }

        return view('admin/absen_manual', [
            'title'        => 'Input Absen Manual',
            'list_opd'     => $list_opd,
            'pegawai'      => $pegawai,
            'selected_opd' => $id_final_opd,
            'level'        => $level
        ]);
    }

    public function simpan_manual()
    {
        $db      = \Config\Database::connect();
        $request = \Config\Services::request();
        $session = session();

        // 1. Tangkap Data dari Form
        $nip        = $request->getPost('nip');
        $tanggal    = $request->getPost('tanggal');
        $kategori   = $request->getPost('kategori');
        $jam_masuk  = $request->getPost('jam_masuk');
        $jam_pulang = $request->getPost('jam_pulang');
        $keterangan = $request->getPost('keterangan');

        // 2. Ambil Data Pegawai
        $pegawai = $db->table('pegawai')
            ->where('nip', $nip)
            ->get()->getRow();

        if (!$pegawai) {
            return redirect()->back()->with('error', 'Data pegawai tidak ditemukan!');
        }

        // 3. Cek apakah sudah ada absen di tanggal tersebut (PWA/Manual sebelumnya)
        $cek = $db->table('presensi')
            ->where(['nip' => $nip, 'tanggal' => $tanggal])
            ->get()->getRow();

        // 4. Siapkan Data Base (Data yang akan disimpan/diupdate)
        $data = [
            'id_pegawai'            => $pegawai->id_pegawai,
            'nip'                   => $nip,
            'tanggal'               => $tanggal,
            'jam_masuk_aktual'      => $jam_masuk,
            'jam_pulang_aktual'     => $jam_pulang,
            'jam_siang'             => ($kategori == 'Hadir') ? '12:05:00' : null,
            'status_masuk'          => 'Tepat Waktu', // Paksa Tepat Waktu agar tidak potong TPP
            'status_pulang'         => 'Selesai',     // Paksa Selesai agar tidak potong TPP
            'menit_keterlambatan'   => 0,
            'kategori'              => $kategori,
            'keterangan'            => $keterangan . " (Input/Update Manual oleh Admin: " . $session->get('nama') . ")",
            'latitude'              => 'Manual',
            'longitude'             => 'Manual',
            'device_info'           => 'Web Admin',
        ];

        if ($cek) {
            // --- LOGIKA UPDATE (Jika sudah ada data PWA/Lainnya) ---
            $data['updated_at'] = date('Y-m-d H:i:s');
            $eksekusi = $db->table('presensi')
                ->where('id_presensi', $cek->id_presensi) // Menggunakan ID dari data yang ditemukan
                ->update($data);

            $pesan = 'Data presensi ' . $pegawai->nama_lengkap . ' pada tanggal ' . $tanggal . ' berhasil diperbarui.';
        } else {
            // --- LOGIKA INSERT (Jika belum ada data sama sekali) ---
            $data['created_at'] = date('Y-m-d H:i:s');
            $eksekusi = $db->table('presensi')->insert($data);

            $pesan = 'Presensi manual untuk ' . $pegawai->nama_lengkap . ' berhasil disimpan.';
        }

        // 5. Response
        if ($eksekusi) {
            return redirect()->to(base_url('rekap/manual'))->with('success', $pesan);
        } else {
            return redirect()->back()->with('error', 'Gagal memproses data ke database.');
        }
    }

    public function harian()
    {
        $db = \Config\Database::connect();
        $request = \Config\Services::request();
        $session = session();

        $level = $session->get('level');
        $id_opd_admin = $session->get('id_opd');

        // Filter Tanggal (Default hari ini)
        $tanggal = $request->getGet('tanggal') ?? date('Y-m-d');
        
        // Filter OPD
        $id_opd = $request->getGet('id_opd');
        if (!in_array($level, ['Superadmin', 'kabupaten'])) {
            $id_opd = $id_opd_admin;
        }

        $list_opd = $db->table('opd')->orderBy('nama_opd', 'ASC')->get()->getResultArray();

        // Query Utama: Pegawai + Presensi pada tanggal terpilih
        $builder = $db->table('pegawai p')
            ->select('p.id_pegawai, p.nip, p.nama_lengkap, p.eselon, o.nama_opd, pr.jam_masuk_aktual, pr.jam_siang, pr.jam_pulang_aktual, pr.kategori')
            ->join('opd o', 'p.id_opd = o.id_opd', 'left')
            ->join('presensi pr', "p.id_pegawai = pr.id_pegawai AND pr.tanggal = '$tanggal'", 'left');

        // Logika Filter OPD & Eselon (Sama dengan index)
        if ($id_opd == 'rekap_eselon_2') {
            $builder->whereIn('p.eselon', ['II.a', 'II.b']);
        } elseif ($id_opd == 'rekap_eselon_3') {
            $builder->whereIn('p.eselon', ['III.a', 'III.b']);
        } elseif ($id_opd == 'rekap_eselon_4') {
            $builder->whereIn('p.eselon', ['IV.a', 'IV.b']);
        } elseif ($id_opd) {
            $builder->where('p.id_opd', $id_opd);
        }

        // Urutkan berdasarkan Eselon baru Nama
        $results = $builder->orderBy("CASE 
                WHEN TRIM(eselon) = 'II.a' THEN 1 WHEN TRIM(eselon) = 'II.b' THEN 2
                WHEN TRIM(eselon) = 'III.a' THEN 3 WHEN TRIM(eselon) = 'III.b' THEN 4
                WHEN TRIM(eselon) = 'IV.a' THEN 5 WHEN TRIM(eselon) = 'IV.b' THEN 6
                ELSE 7 END", "ASC", false)
            ->orderBy('p.nama_lengkap', 'ASC')
            ->get()->getResultArray();

        $rekap_harian = [];
        foreach ($results as $r) {
            $jam = $r['jam_masuk_aktual'];
            $status = "Tanpa Keterangan";
            $bg = "badge-light text-muted";

            // LOGIKA PENILAIAN WAKTU ON-THE-FLY
            if ($r['kategori'] && $r['kategori'] != 'Hadir') {
                $status = $r['kategori'];
                $bg = "badge-info text-dark";
            } elseif ($jam) {
                // =========================================================================
                // MODIFIKASI WARNA REKAP HARIAN (Sinkron dengan Index)
                // =========================================================================
                if ($jam <= '07:30:00') {
                    $status = "Sangat Baik / Istimewa"; 
                    $bg = "text-white\" style=\"background-color: #155724;";
                } elseif ($jam <= '07:45:00') {
                    $status = "Baik"; 
                    $bg = "text-white\" style=\"background-color: #28a745;";
                } elseif ($jam <= '08:15:00') {
                    $status = "Cukup Baik"; 
                    $bg = "text-dark\" style=\"background-color: #8ce196;";
                } elseif ($jam <= '09:00:00') {
                    $status = "Terlambat"; 
                    $bg = "text-dark\" style=\"background-color: #fff3cd;";
                } elseif ($jam <= '10:00:00') {
                    $status = "Pembinaan"; 
                    $bg = "text-dark\" style=\"background-color: #ffc107;";
                } else {
                    $status = "Teguran"; 
                    $bg = "text-white bg-danger";
                }
            }

            $r['status_label'] = $status;
            $r['status_bg'] = $bg;
            $rekap_harian[] = $r;
        }

        $data = [
            'title'        => 'Rekap Harian Presensi',
            'rekap'        => $rekap_harian,
            'list_opd'     => $list_opd,
            'tanggal'      => $tanggal,
            'selected_opd' => $id_opd
        ];

        return view('admin/rekap_harian', $data);
    }
}