<?php

namespace App\Controllers;

class Pwa extends BaseController
{
    protected $db;

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

    public function index()
    {
        $id_pegawai = session()->get('id_pegawai');

        if (!$id_pegawai || !session()->get('logged_in')) {
            session()->destroy();
            return redirect()->to('/authpegawai');
        }

        // [OPTIMASI 1]: Lepas Session Lock
        session_write_close();

        // 1. Ambil data pegawai (Cukup 1x Query)
        $pegawai = $this->db->table('pegawai')
            ->select('pegawai.*, opd.id_jam_kerja as id_jam_opd, opd.nama_opd')
            ->join('opd', 'pegawai.id_opd = opd.id_opd', 'left')
            ->where('id_pegawai', $id_pegawai)
            ->get()->getRowArray();

        if (!$pegawai) {
            return redirect()->to('/authpegawai');
        }

        $tanggal_hari_ini = date('Y-m-d');
        $nama_hari_indo = $this->get_nama_hari(date('D'));

        // 2. Cache Data Libur
        if (!$libur_data = cache('libur_global_cache')) {
            $libur_data = [
                'hari_ini' => $this->db->table('hari_libur')->where('tanggal', $tanggal_hari_ini)->get()->getRowArray(),
                'mendatang' => $this->db->table('hari_libur')->where('tanggal >', $tanggal_hari_ini)->limit(5)->get()->getResultArray()
            ];
            cache()->save('libur_global_cache', $libur_data, 3600);
        }

        // 3. Penentuan Jadwal
        $cek_plotting = $this->db->table('plotting_shift')
            ->where(['id_pegawai' => $id_pegawai, 'tanggal' => $tanggal_hari_ini])
            ->get()->getRow();

        $id_final_jam = ($cek_plotting) ? $cek_plotting->id_jam_kerja : ($pegawai['id_jam_opd'] ?? 1);

        $jadwal_hari_ini = $this->db->table('jam_kerja_detail')
            ->where(['id_jam_kerja' => $id_final_jam, 'hari' => $nama_hari_indo])
            ->get()->getRowArray();

        // 4. Riwayat
        $filter_bulan = $this->request->getGet('bulan') ?? date('m');
        $filter_tahun = $this->request->getGet('tahun') ?? date('Y');

        // [OPTIMASI 2]: SARGable Query untuk range tanggal
        $start_date = sprintf('%04d-%02d-01', $filter_tahun, $filter_bulan);
        $end_date   = date('Y-m-t', strtotime($start_date));

        $riwayat = $this->db->table('presensi')
            ->where('id_pegawai', $id_pegawai)
            ->where('tanggal >=', $start_date)
            ->where('tanggal <=', $end_date)
            ->orderBy('tanggal', 'DESC')
            ->get()->getResultArray();

        $terakhir = null;
        foreach ($riwayat as $r) {
            if ($r['tanggal'] == $tanggal_hari_ini) {
                $terakhir = $r;
                break;
            }
        }

        // 5. Cek Penugasan Apel Hari Ini
        $tugas_apel = $this->db->table('apel_peserta')
            ->select('apel.*, apel_peserta.jam_absen as sudah_absen_apel')
            ->join('apel', 'apel.id_apel = apel_peserta.id_apel')
            ->where('apel_peserta.id_pegawai', $id_pegawai)
            ->where('apel.tanggal', $tanggal_hari_ini)
            ->get()->getRowArray();

        // 6. CEK PENGAJUAN IZIN / SAKIT / TL AKTIF HARI INI
        $pengajuan_aktif = $this->db->table('pengajuan_absen')
            ->where('nip', $pegawai['nip'])
            ->where('tanggal_mulai <=', $tanggal_hari_ini)
            ->where('tanggal_selesai >=', $tanggal_hari_ini)
            ->orderBy('created_at', 'DESC')
            ->get()->getRowArray();

        return view('pwa/index', [
            'pegawai'         => $pegawai,
            'jadwal_hari_ini' => $jadwal_hari_ini,
            'libur'           => $libur_data['hari_ini'],
            'libur_mendatang' => $libur_data['mendatang'],
            'terakhir'        => $terakhir,
            'riwayat'         => $riwayat,
            'bulan_aktif'     => $filter_bulan,
            'tahun_aktif'     => $filter_tahun,
            'face_data'       => $pegawai['face_vector'] ?? null,
            'tugas_apel'      => $tugas_apel,
            'pengajuan_aktif' => $pengajuan_aktif
        ]);
    }

    // --- FUNGSI SIMPAN WAJAH (DIKEMBALIKAN) ---
    public function simpan_wajah_pwa()
    {
        $id = session()->get('id_pegawai');
        $v = $this->request->getPost('face_vector');

        if ($v && $this->db->table('pegawai')->where('id_pegawai', $id)->update(['face_vector' => $v])) {
            return $this->response->setJSON(['status' => 'success', 'message' => 'Wajah terdaftar!']);
        }
        return $this->response->setJSON(['status' => 'error', 'message' => 'Gagal daftar wajah.']);
    }

    public function submit_absen_apel()
    {
        $id_pegawai = session()->get('id_pegawai');

        if (!$id_pegawai) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Sesi berakhir, silakan login ulang.']);
        }

        session_write_close();

        $lat_user   = (float) $this->request->getPost('latitude');
        $lng_user   = (float) $this->request->getPost('longitude');
        $id_apel    = $this->request->getPost('id_apel');

        $this->db->transStart();
        try {
            $tanggal      = date('Y-m-d');
            $jam_sekarang = date('H:i:s');

            $event = $this->db->table('apel')->where('id_apel', $id_apel)->get()->getRow();
            if (!$event) throw new \Exception('Jadwal apel tidak ditemukan.');

            $jarak = $this->calculate_distance($lat_user, $lng_user, (float)$event->latitude, (float)$event->longitude);
            if ($jarak > (float)($event->radius ?? 100)) {
                throw new \Exception("Di luar radius upacara! Jarak Anda: " . round($jarak) . " meter.");
            }

            $this->db->table('apel_peserta')->where(['id_apel' => $id_apel, 'id_pegawai' => $id_pegawai])->update([
                'jam_absen' => $jam_sekarang
            ]);

            $cek_harian = $this->db->table('presensi')->where(['id_pegawai' => $id_pegawai, 'tanggal' => $tanggal])->get()->getRow();

            if (!$cek_harian) {
                $pegawai = $this->db->table('pegawai')->select('nip, id_opd')->where('id_pegawai', $id_pegawai)->get()->getRow();
                $jam_seharusnya = $event->jam_mulai;

                $this->db->table('presensi')->insert([
                    'id_pegawai'            => $id_pegawai,
                    'nip'                   => $pegawai->nip,
                    'tanggal'               => $tanggal,
                    'jam_masuk_aktual'      => $jam_sekarang,
                    'jam_masuk_seharusnya'  => $jam_seharusnya,
                    'jam_pulang_seharusnya' => $event->jam_akhir,
                    'status_masuk'          => 'Hadir (Apel)',
                    'kategori'              => 'Hadir',
                    'latitude'              => $lat_user,
                    'longitude'             => $lng_user,
                    'deskripsi'             => "Hadir melalui sistem absen apel di " . $event->nama_apel . " (Otomatis)",
                    'created_at'            => date('Y-m-d H:i:s')
                ]);
            }

            $this->db->transComplete();
            return $this->response->setJSON([
                'status' => 'success',
                'message' => "<b>Absen Apel Berhasil!</b><br>Data presensi harian Anda otomatis terisi sebagai 'Hadir (Apel)'."
            ]);
        } catch (\Exception $e) {
            $this->db->transRollback();
            return $this->response->setJSON(['status' => 'error', 'message' => $e->getMessage()]);
        }
    }

    public function submit_absen()
    {
        $id_pegawai = session()->get('id_pegawai');
        session_write_close();

        $lat_user    = (float) ($this->request->getPost('latitude'));
        $lng_user    = (float) ($this->request->getPost('longitude'));
        $device_info = $this->request->getPost('device_info');
        $nip_user    = $this->request->getPost('nip');

        if (empty($lat_user) || empty($lng_user) || $lat_user == 0 || $lng_user == 0) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Gagal mendeteksi lokasi. Pastikan GPS aktif.']);
        }

        if (cache("lock_absen_$id_pegawai")) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Sedang memproses, mohon tunggu...']);
        }
        cache()->save("lock_absen_$id_pegawai", true, 5);

        $this->db->transStart();
        try {
            $tanggal         = date('Y-m-d');
            $jam_sekarang    = date('H:i:s');
            $hari_angka      = date('N');
            $nama_hari_indo  = $this->get_nama_hari(date('D'));
            $jam_mulai_siang = ($hari_angka == 5) ? '11:30:00' : '12:00:00';

            if ($jam_sekarang < '07:00:00') {
                throw new \Exception('Sistem sedang tutup. Silakan absen mulai pukul 07:00 WITA.');
            }

            // OPTIMASI CACHE PEGAWAI
            $cache_user = "user_info_$id_pegawai";
            if (!$user_info = cache($cache_user)) {
                $user_info = $this->db->table('pegawai')
                    ->select('pegawai.*, opd.latitude as lat_pusat, opd.longitude as lng_pusat, opd.radius as radius_opd, opd.id_jam_kerja as jam_opd')
                    ->join('opd', 'pegawai.id_opd = opd.id_opd', 'left')
                    ->where('id_pegawai', $id_pegawai)
                    ->get()->getRow();
                if ($user_info) cache()->save($cache_user, $user_info, 60);
            }
            if (!$user_info) throw new \Exception('Data pegawai tidak ditemukan.');

            $cek_plotting = $this->db->table('plotting_shift')
                ->where(['id_pegawai' => $id_pegawai, 'tanggal' => $tanggal])
                ->get()->getRow();

            // [TAMBAHAN]: Cek Plotting Format Range
            if (!$cek_plotting && $this->db->fieldExists('tanggal_mulai', 'plotting_shift')) {
                $cek_plotting = $this->db->table('plotting_shift')
                    ->where('id_pegawai', $id_pegawai)
                    ->where('tanggal_mulai <=', $tanggal)
                    ->where('tanggal_selesai >=', $tanggal)
                    ->get()->getRow();
            }

            $id_final_jam = ($cek_plotting) ? $cek_plotting->id_jam_kerja : ($user_info->jam_opd ?? 1);

            // OPTIMASI CACHE JADWAL
            $cache_jadwal = "jadwal_{$id_final_jam}_{$nama_hari_indo}";
            if (!$jadwal = cache($cache_jadwal)) {
                $jadwal = $this->db->table('jam_kerja_detail')
                    ->where(['id_jam_kerja' => $id_final_jam, 'hari' => $nama_hari_indo])
                    ->get()->getRowArray();
                if ($jadwal) cache()->save($cache_jadwal, $jadwal, 60); 
            }
            if (!$jadwal) throw new \Exception("Hari ini ($nama_hari_indo) tidak ada jadwal kerja untuk Anda.");

            // LOGIKA RADIUS
            $is_dalam_radius   = false;
            $nama_lokasi_absen = "";
            $jarak_terdekat    = 9999999;

            if (!empty($user_info->id_lokasi)) {
                $ids = array_filter(explode(',', $user_info->id_lokasi));

                if (!$daftar_lokasi = cache('global_opd_lokasi')) {
                    $daftar_lokasi = $this->db->table('opd_lokasi')->get()->getResultArray();
                    cache()->save('global_opd_lokasi', $daftar_lokasi, 3600 * 24);
                }

                foreach ($daftar_lokasi as $lok) {
                    if (in_array($lok['id_lokasi'], $ids)) {
                        $jarak = $this->calculate_distance($lat_user, $lng_user, (float)$lok['latitude'], (float)$lok['longitude']);
                        if ($jarak < $jarak_terdekat) $jarak_terdekat = $jarak;
                        if ($jarak <= (float)($lok['radius_meter'] ?? 60)) {
                            $is_dalam_radius = true;
                            $nama_lokasi_absen = $lok['nama_lokasi'];
                            break;
                        }
                    }
                }
            }

            if (!$is_dalam_radius && $user_info->lat_pusat != 0) {
                $jarak = $this->calculate_distance($lat_user, $lng_user, (float)$user_info->lat_pusat, (float)$user_info->lng_pusat);
                if ($jarak < $jarak_terdekat) $jarak_terdekat = $jarak;
                if ($jarak <= (float)($user_info->radius_opd ?? 60)) {
                    $is_dalam_radius = true;
                    $nama_lokasi_absen = "Kantor Induk";
                }
            }

            if (!$is_dalam_radius) {
                $pesan_jarak = ($jarak_terdekat > 1000000) ? "Lokasi tidak valid." : round($jarak_terdekat) . " meter";
                throw new \Exception("Di luar radius! Jarak Anda: " . $pesan_jarak);
            }

            $cek = $this->db->table('presensi')->where(['id_pegawai' => $id_pegawai, 'tanggal' => $tanggal])->get()->getRowArray();
            $msg = "";

            // NORMALISASI JAM
            $jam_target = !empty($jadwal['jam_masuk']) ? str_replace('.', ':', $jadwal['jam_masuk']) : '07:30:00';
            $jam_pulang_target = !empty($jadwal['jam_pulang']) ? str_replace('.', ':', $jadwal['jam_pulang']) : '16:00:00';

            if (strlen($jam_target) == 5) $jam_target .= ':00';
            if (strlen($jam_pulang_target) == 5) $jam_pulang_target .= ':00';

            if (!$cek) {
                // ABSEN MASUK
                $waktu_aktual = strtotime($jam_sekarang);
                $waktu_target = strtotime($jam_target);
                $menit_keterlambatan = 0;

                if ($waktu_aktual > $waktu_target) {
                    $menit_keterlambatan = floor(($waktu_aktual - $waktu_target) / 60);
                }

                $batas_baik  = $jadwal['batas_baik_menit'] ?? 15;
                $batas_cukup = $jadwal['batas_cukup_menit'] ?? 45;
                $batas_telat = $jadwal['batas_telat_menit'] ?? 90;
                $batas_bina  = $jadwal['batas_bina_menit'] ?? 150;

                if ($menit_keterlambatan <= 0) $status_m = 'Sangat Baik / Istimewa';
                elseif ($menit_keterlambatan <= $batas_baik) $status_m = 'Baik';
                elseif ($menit_keterlambatan <= $batas_cukup) $status_m = 'Cukup Baik';
                elseif ($menit_keterlambatan <= $batas_telat) $status_m = 'Terlambat';
                elseif ($menit_keterlambatan <= $batas_bina) $status_m = 'Pembinaan';
                else $status_m = 'Teguran';

                $this->db->table('presensi')->insert([
                    'id_pegawai'            => $id_pegawai,
                    'tanggal'               => $tanggal,
                    'jam_masuk_aktual'      => $jam_sekarang,
                    'jam_masuk_seharusnya'  => $jam_target,
                    'jam_pulang_seharusnya' => $jam_pulang_target,
                    'status_masuk'          => $status_m,
                    'menit_keterlambatan'   => $menit_keterlambatan,
                    'id_jam_kerja_snapshot' => $id_final_jam,
                    'latitude'              => $lat_user,
                    'longitude'             => $lng_user,
                    'device_info'           => $device_info,
                    'nip'                   => $nip_user,
                    'kategori'              => 'Hadir',
                    'created_at'            => date('Y-m-d H:i:s')
                ]);
                
                // [PANGGIL PESAN RANDOM MASUK]
                $pantun = $this->getRandomPantun('Masuk', $user_info->nama_lengkap);
                $msg = "Absen Masuk ($status_m) Berhasil di $nama_lokasi_absen!<br><br>$pantun";
                
            } else {
                // PROTEKSI DOUBLE HIT (2 MENIT)
                $waktu_terakhir = !empty($cek['updated_at']) ? $cek['updated_at'] : $cek['created_at'];
                if ($waktu_terakhir && (strtotime(date('Y-m-d H:i:s')) - strtotime($waktu_terakhir) < 120)) {
                    throw new \Exception('Terlalu cepat! Mohon tunggu 2 menit sebelum absen lagi.');
                }

                $batas_mulai_pulang = date('H:i:s', strtotime('-30 minutes', strtotime($jam_pulang_target)));

                // ABSEN SIANG
                if ($jam_sekarang >= $jam_mulai_siang && $jam_sekarang <= '13:30:00' && empty($cek['jam_siang'])) {
                    $this->db->table('presensi')->where('id_presensi', $cek['id_presensi'])->update([
                        'jam_siang'  => $jam_sekarang,
                        'updated_at' => date('Y-m-d H:i:s')
                    ]);
                    
                    // [PANGGIL PESAN RANDOM SIANG]
                    $pantun = $this->getRandomPantun('Siang', $user_info->nama_lengkap);
                    $msg = "Absen Siang Berhasil!<br><br>$pantun";
                    
                } 
                // CEK JIKA KLIK DI WAKTU KOSONG (SEBELUM WAKTUNYA PULANG)
                elseif ($jam_sekarang > '13:30:00' && $jam_sekarang < $batas_mulai_pulang) {
                    throw new \Exception('Belum waktunya Absen Pulang. Anda bisa absen pulang mulai pukul ' . date('H:i', strtotime($batas_mulai_pulang)) . ' WITA.');
                }
                // ABSEN PULANG
                elseif ($jam_sekarang >= $batas_mulai_pulang) {
                    $status_p = (strtotime($jam_sekarang) < strtotime($jam_pulang_target)) ? 'Cepat Pulang' : 'Selesai';
                    
                    $this->db->table('presensi')->where('id_presensi', $cek['id_presensi'])->update([
                        'jam_pulang_aktual'     => $jam_sekarang,
                        'jam_pulang_seharusnya' => $jam_pulang_target,
                        'status_pulang'         => $status_p,
                        'updated_at'            => date('Y-m-d H:i:s')
                    ]);

                    // [PANGGIL PESAN RANDOM PULANG]
                    $pantun = $this->getRandomPantun('Pulang', $user_info->nama_lengkap);
                    $msg = "Absen Pulang Berhasil! Jam diperbarui: " . date('H:i', strtotime($jam_sekarang)) . " ($status_p)<br><br>$pantun";
                    
                } else {
                    throw new \Exception('Sesi absensi tidak valid saat ini.');
                }
            }

            $this->db->transComplete();
            cache()->delete("lock_absen_$id_pegawai");
            return $this->response->setJSON(['status' => 'success', 'message' => "$msg"]);
        } catch (\Exception $e) {
            $this->db->transRollback();
            cache()->delete("lock_absen_$id_pegawai");
            return $this->response->setJSON(['status' => 'error', 'message' => $e->getMessage()]);
        }
    }

    // =========================================================================
    // [FIX]: PERBAIKAN LOGIKA SUBMIT IZIN/SAKIT & BACKDATE (TANGGAL MUNDUR)
    // =========================================================================
    public function submit_izin_pwa()
    {
        $nip = session()->get('nip');

        if (!$nip) {
            $nip = $this->request->getPost('nip_manual');
        }

        if (!$nip || $nip == "") {
            return $this->response->setJSON([
                'status'  => 'error',
                'message' => 'Sesi Identitas (NIP) tidak ditemukan. Silakan refresh halaman.'
            ]);
        }

        $kategori     = $this->request->getPost('kategori');
        $sub_kategori = $this->request->getPost('sub_kategori');
        $slot_waktu   = $this->request->getPost('slot_waktu') ?? 'Penuh';

        // [FIX BACKDATE]: Ambil input tanggal secara eksplisit.
        // Jika input kosong, baru default ke hari ini. Jika user pilih tgl kemarin, variabel ini akan berisi tgl kemarin.
        $tgl_mulai = $this->request->getPost('tgl_mulai');
        if (empty($tgl_mulai)) $tgl_mulai = date('Y-m-d');

        $tgl_selesai = $this->request->getPost('tgl_selesai');
        if (empty($tgl_selesai)) $tgl_selesai = $tgl_mulai; // Jika selesai kosong, samakan dengan mulai

        // File Upload Logic
        $file = $this->request->getFile('file_bukti');
        $namaFile = "";
        if ($file && $file->isValid() && !$file->hasMoved()) {
            $namaFile = $file->getRandomName();
            $file->move('uploads/bukti_absen/', $namaFile);
        }

        $data = [
            'nip'             => $nip,
            'kategori'        => $kategori,
            'sub_kategori'    => $sub_kategori,
            'slot_waktu'      => $slot_waktu,
            'tanggal_mulai'   => $tgl_mulai,   // Gunakan variabel yang sudah divalidasi
            'tanggal_selesai' => $tgl_selesai, // Gunakan variabel yang sudah divalidasi
            'keterangan'      => $this->request->getPost('alasan') ?: $this->request->getPost('keterangan'),
            'file_bukti'      => $namaFile,
            'status_approval' => 'Pending',
            'created_at'      => date('Y-m-d H:i:s')
        ];

        $db = \Config\Database::connect();
        try {
            $db->table('pengajuan_absen')->insert($data);
            return $this->response->setJSON(['status' => 'success', 'message' => 'Pengajuan berhasil terkirim!']);
        } catch (\Exception $e) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Gagal simpan ke database.']);
        }
    }

    // =========================================================================
    // [FIX]: LOGIKA APPROVAL UNTUK MENANGANI TL DALAM DAERAH "PENUH"
    // =========================================================================
    public function setujui_pengajuan($id_pengajuan)
    {
        $db = \Config\Database::connect();

        $pengajuan = $db->table('pengajuan_absen')->where('id_pengajuan', $id_pengajuan)->get()->getRowArray();

        if (!$pengajuan) return "Data tidak ditemukan";

        $begin = new \DateTime($pengajuan['tanggal_mulai']);
        $end   = new \DateTime($pengajuan['tanggal_selesai']);
        $end->modify('+1 day');
        $interval = new \DateInterval('P1D');
        $daterange = new \DatePeriod($begin, $interval, $end);

        foreach ($daterange as $date) {
            $tgl = $date->format("Y-m-d");
            $nip = $pengajuan['nip'];

            $cekPresensi = $db->table('presensi')->where(['nip' => $nip, 'tanggal' => $tgl])->get()->getRowArray();

            $updateData = [];

            // [LOGIKA BARU]: Tambahkan kondisi jika "Dalam Daerah" tapi slot waktunya "Penuh"
            $is_full_day = false;
            if (
                $pengajuan['sub_kategori'] == 'Penuh' ||
                $pengajuan['sub_kategori'] == 'Luar Daerah' ||
                $pengajuan['kategori'] == 'Sakit' ||
                ($pengajuan['sub_kategori'] == 'Dalam Daerah' && $pengajuan['slot_waktu'] == 'Penuh')
            ) {
                $is_full_day = true;
            }

            if ($is_full_day) {
                // Jika Penuh/Sakit/Luar Daerah/TL Dalam Daerah Full -> Isi Semua Slot
                $updateData = [
                    'jam_masuk_aktual'  => '00:01:00',
                    'jam_siang'         => '00:01:00',
                    'jam_pulang_aktual' => '00:01:00',
                    'status_masuk'      => $pengajuan['kategori'],
                    'status_pulang'     => 'Selesai',
                    'deskripsi'         => $pengajuan['kategori'] . " (" . $pengajuan['sub_kategori'] . ")"
                ];
            } else {
                // Jika Parsial (Pagi/Siang/Sore)
                if ($pengajuan['slot_waktu'] == 'Pagi') {
                    $updateData['jam_masuk_aktual'] = '00:01:00';
                    $updateData['status_masuk']     = $pengajuan['kategori'];
                } elseif ($pengajuan['slot_waktu'] == 'Siang') {
                    $updateData['jam_siang']        = '00:01:00';
                } elseif ($pengajuan['slot_waktu'] == 'Sore') {
                    $updateData['jam_pulang_aktual'] = '00:01:00';
                    $updateData['status_pulang']     = 'Selesai';
                }
                $updateData['deskripsi'] = "Izin/TL Sebagian: " . $pengajuan['slot_waktu'];
            }

            if ($cekPresensi) {
                $db->table('presensi')->where('id_presensi', $cekPresensi['id_presensi'])->update($updateData);
            } else {
                $updateData['nip'] = $nip;
                $updateData['tanggal'] = $tgl;
                // Tambahan: Pastikan id_pegawai juga tersimpan jika insert baru (ambil dari tabel pegawai)
                $pegawaiInfo = $db->table('pegawai')->select('id_pegawai')->where('nip', $nip)->get()->getRow();
                if ($pegawaiInfo) $updateData['id_pegawai'] = $pegawaiInfo->id_pegawai;

                $db->table('presensi')->insert($updateData);
            }
        }

        $db->table('pengajuan_absen')->where('id_pengajuan', $id_pengajuan)->update(['status_approval' => 'Disetujui']);

        return redirect()->back()->with('success', 'Pengajuan disetujui dan presensi diperbarui!');
    }

    // --- HELPER FUNCTIONS ---
    private function calculate_distance($lat1, $lon1, $lat2, $lon2)
    {
        $earth_radius = 6371000;
        $dLat = deg2rad($lat2 - $lat1);
        $dLon = deg2rad($lon2 - $lon1);
        $a = sin($dLat / 2) * sin($dLat / 2) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLon / 2) * sin($dLon / 2);
        $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
        return $earth_radius * $c;
    }

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

    public function update_password()
    {
        $id = session()->get('id_pegawai');
        $user = $this->db->table('pegawai')->where('id_pegawai', $id)->get()->getRowArray();
        if (password_verify($this->request->getPost('password_lama'), $user['password'])) {
            if ($this->request->getPost('password_baru') === $this->request->getPost('konfirmasi_password')) {
                $this->db->table('pegawai')->where('id_pegawai', $id)->update(['password' => password_hash($this->request->getPost('password_baru'), PASSWORD_DEFAULT)]);
                return $this->response->setJSON(['status' => 'success', 'message' => 'Password diubah.']);
            }
        }
        return $this->response->setJSON(['status' => 'error', 'message' => 'Gagal ganti password.']);
    }

    // --- TAMBAHKAN FUNGSI INI DI PALING BAWAH KELAS PWA ---
    private function getRandomPantun($tipe, $nama_pegawai)
    {
        // Ambil 1 pesan acak dari database berdasarkan tipe yang aktif
        $pesan = $this->db->table('pesan_absen')
            ->where('tipe', $tipe)
            ->where('is_active', 1)
            ->orderBy('RAND()')
            ->limit(1)
            ->get()->getRow();

        if ($pesan) {
            // Ganti string {nama} dengan nama asli pegawai
            return str_replace('{nama}', "<b>" . $nama_pegawai . "</b>", $pesan->pesan);
        }

        // Fallback default jika database pesan masih kosong
        if ($tipe == 'Masuk') return "Selamat bekerja, <b>$nama_pegawai</b>!";
        if ($tipe == 'Siang') return "Selamat beristirahat, <b>$nama_pegawai</b>!";
        return "Hati-hati di jalan, <b>$nama_pegawai</b>!";
    }
}
