<?php

namespace App\Controllers;

use DateTime;
use DateInterval;
use DatePeriod;

class Approval extends BaseController
{
    protected $db;

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

    public function index()
    {
        $level        = session()->get('level');
        $id_opd_admin = session()->get('id_opd');
        $filter_opd   = $this->request->getGet('id_opd');
        $search       = $this->request->getGet('keyword');

        // BACA DARI TABEL PENGAJUAN
        $builder = $this->db->table('pengajuan_absen')
            ->select('pengajuan_absen.*, pegawai.nama_lengkap, pegawai.id_pegawai, opd.nama_opd')
            ->join('pegawai', 'pengajuan_absen.nip = pegawai.nip', 'left')
            ->join('opd', 'pegawai.id_opd = opd.id_opd', 'left');

        // 1. KUNCI ANTREAN: Hanya yang berstatus 'Pending'
        $builder->where('pengajuan_absen.status_approval', 'Pending');

        // 2. FILTER HAK AKSES & OPD
        if (in_array($level, ['Superadmin', 'kabupaten'])) {
            if ($filter_opd) {
                $builder->where('pegawai.id_opd', $filter_opd);
            }
        } else {
            $builder->where('pegawai.id_opd', $id_opd_admin);
        }

        // 3. FILTER PENCARIAN
        if ($search) {
            $builder->groupStart()
                ->like('pegawai.nama_lengkap', $search)
                ->orLike('pengajuan_absen.nip', $search)
                ->groupEnd();
        }

        $perPage = 50; 
        $currentPage = (int)($this->request->getVar('page_pengajuan') ?? 1);
        $totalCount = $builder->countAllResults(false);

        $pengajuan = $builder->orderBy('pengajuan_absen.created_at', 'DESC')
            ->limit($perPage, ($currentPage - 1) * $perPage)
            ->get()->getResultArray();

        $pager = service('pager');
        $pager_links = $pager->makeLinks($currentPage, $perPage, $totalCount, 'bootstrap_pagination', 0, 'pengajuan');

        $data = [
            'pengajuan'    => $pengajuan,
            'list_opd'     => $this->db->table('opd')->orderBy('nama_opd', 'ASC')->get()->getResultArray(),
            'pager'        => $pager_links,
            'level'        => $level,
            'keyword'      => $search,
            'selected_opd' => $filter_opd,
            'title'        => 'Antrean Approval Izin & Sakit'
        ];

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

    public function riwayat()
    {
        $level        = session()->get('level');
        $id_opd_admin = session()->get('id_opd');
        $filter_opd   = $this->request->getGet('id_opd');
        $search       = $this->request->getGet('keyword');

        $builder = $this->db->table('pengajuan_absen')
            ->select('pengajuan_absen.*, pegawai.nama_lengkap, opd.nama_opd')
            ->join('pegawai', 'pengajuan_absen.nip = pegawai.nip', 'left')
            ->join('opd', 'pegawai.id_opd = opd.id_opd', 'left');

        // 1. KUNCI RIWAYAT: Yang sudah diproses (Disetujui/Ditolak)
        $builder->where('pengajuan_absen.status_approval !=', 'Pending');

        if (in_array($level, ['Superadmin', 'kabupaten'])) {
            if ($filter_opd) $builder->where('pegawai.id_opd', $filter_opd);
        } else {
            $builder->where('pegawai.id_opd', $id_opd_admin);
        }

        if ($search) {
            $builder->groupStart()
                ->like('pegawai.nama_lengkap', $search)
                ->orLike('pengajuan_absen.nip', $search)
                ->groupEnd();
        }

        $perPage = 50; 
        $currentPage = (int)($this->request->getVar('page_riwayat') ?? 1);
        $totalCount = $builder->countAllResults(false); 

        $riwayat = $builder->orderBy('pengajuan_absen.created_at', 'DESC') 
            ->limit($perPage, ($currentPage - 1) * $perPage)
            ->get()->getResultArray();

        $pager = service('pager');
        $pager_links = $pager->makeLinks($currentPage, $perPage, $totalCount, 'bootstrap_pagination', 0, 'riwayat');

        $data = [
            'riwayat'      => $riwayat,
            'list_opd'     => $this->db->table('opd')->orderBy('nama_opd', 'ASC')->get()->getResultArray(),
            'keyword'      => $search,
            'selected_opd' => $filter_opd,
            'pager'        => $pager_links, 
            'level'        => $level,
            'title'        => 'Riwayat Approval Selesai'
        ];

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

    public function proses()
    {
        $id_pengajuan = $this->request->getPost('id_pengajuan');
        $aksi         = $this->request->getPost('aksi');
        $catatan      = $this->request->getPost('catatan');

        $this->eksekusi_approval($id_pengajuan, $aksi, $catatan);

        return redirect()->to(base_url('approval'))->with('success', 'Data berhasil diproses.');
    }

    public function proses_massal()
    {
        $ids = json_decode($this->request->getPost('ids'));
        $aksi = $this->request->getPost('aksi');

        if (empty($ids)) {
            return redirect()->back()->with('error', 'Tidak ada data yang dipilih.');
        }

        foreach ($ids as $id_pengajuan) {
            $this->eksekusi_approval($id_pengajuan, $aksi, "Disetujui Massal oleh Admin");
        }

        return redirect()->to(base_url('approval'))->with('success', count($ids) . ' data berhasil diproses sekaligus.');
    }

    /**
     * CORE ENGINE: Memproses Pengajuan ke Tabel Presensi
     */
    /**
     * CORE ENGINE: Memproses Pengajuan ke Tabel Presensi
     */
    /**
     * CORE ENGINE: Memproses Pengajuan ke Tabel Presensi
     */
    private function eksekusi_approval($id_pengajuan, $aksi, $catatan)
    {
        $pengajuan = $this->db->table('pengajuan_absen')->where('id_pengajuan', $id_pengajuan)->get()->getRow();
        if (!$pengajuan || $pengajuan->status_approval != 'Pending') return false;

        $this->db->transStart();

        // 1. Update Status di tabel pengajuan_absen
        $status_baru = ($aksi == 'setuju') ? 'Disetujui' : 'Ditolak';
        $this->db->table('pengajuan_absen')->where('id_pengajuan', $id_pengajuan)->update([
            'status_approval' => $status_baru,
            'keterangan'      => $pengajuan->keterangan . " | Catatan Admin: " . $catatan
        ]);

        // 2. Jika disetujui, injeksi data ke tabel presensi dengan JAM ACAK SESUAI RENTANG
        if ($aksi == 'setuju') {
            $pegawai = $this->db->table('pegawai')->select('id_pegawai')->where('nip', $pengajuan->nip)->get()->getRow();
            $id_pegawai = $pegawai ? $pegawai->id_pegawai : 0;

            // Setup Date Range (Untuk Izin/Sakit/TL berhari-hari)
            $begin = new DateTime($pengajuan->tanggal_mulai);
            $end   = new DateTime($pengajuan->tanggal_selesai);
            $end->modify('+1 day'); // Agar tanggal selesai ikut terproses
            $interval  = new DateInterval('P1D');
            $daterange = new DatePeriod($begin, $interval, $end);

            foreach ($daterange as $date) {
                $tgl = $date->format("Y-m-d");
                $cek_presensi = $this->db->table('presensi')->where(['nip' => $pengajuan->nip, 'tanggal' => $tgl])->get()->getRowArray();

                $updateData = [
                    'statusijin' => $pengajuan->kategori,
                    'deskripsi'  => $pengajuan->kategori . " (" . $pengajuan->sub_kategori . ") - Approved",
                    'updated_at' => date('Y-m-d H:i:s')
                ];

                // =========================================================================
                // LOGIKA GENERATOR WAKTU CERDAS (SESUAI PERMINTAAN ANDA)
                // =========================================================================
                if ($pengajuan->sub_kategori == 'Setengah Hari' || $pengajuan->sub_kategori == 'Dalam Daerah') {
                    
                    if ($pengajuan->slot_waktu == 'Pagi') {
                        $updateData['jam_masuk_aktual'] = $this->generateRandomTime('07:00:00', '07:30:00');
                        $updateData['status_masuk']     = $pengajuan->kategori;
                    } 
                    elseif ($pengajuan->slot_waktu == 'Siang') {
                        $updateData['jam_siang']        = $this->generateRandomTime('12:00:00', '13:00:00');
                    } 
                    elseif ($pengajuan->slot_waktu == 'Sore') {
                        $updateData['jam_pulang_aktual'] = $this->generateRandomTime('16:30:00', '17:00:00');
                        $updateData['status_pulang']     = $pengajuan->kategori; 
                    }

                } else {
                    // JIKA PENUH (Sakit Penuh, Izin Penuh, TL Luar Daerah)
                    // Mengisi semua jam dengan waktu yang logis
                    $updateData['jam_masuk_aktual']  = $this->generateRandomTime('07:00:00', '07:30:00');
                    $updateData['jam_siang']         = $this->generateRandomTime('12:00:00', '13:00:00');
                    $updateData['jam_pulang_aktual'] = $this->generateRandomTime('16:30:00', '17:00:00');
                    
                    $updateData['status_masuk']  = $pengajuan->kategori;
                    $updateData['status_pulang'] = $pengajuan->kategori;
                    $updateData['kategori']      = $pengajuan->kategori; // Mengganti kategori harian penuh
                }
                // =========================================================================

                if ($cek_presensi) {
                    // Update baris presensi jika sudah ada (misal dia sempat absen pagi, lalu izin siang)
                    $this->db->table('presensi')->where('id_presensi', $cek_presensi['id_presensi'])->update($updateData);
                } else {
                    // Insert baris presensi baru jika belum ada absen sama sekali hari itu
                    $updateData['id_pegawai'] = $id_pegawai;
                    $updateData['nip']        = $pengajuan->nip;
                    $updateData['tanggal']    = $tgl;
                    $updateData['kategori']   = $updateData['kategori'] ?? 'Hadir'; // Default "Hadir" jika hanya izin setengah hari
                    $updateData['created_at'] = date('Y-m-d H:i:s');
                    
                    $this->db->table('presensi')->insert($updateData);
                }
            }
        }

        $this->db->transComplete();
        return $this->db->transStatus();
    }

    private function generateRandomTime($start, $end)
    {
        $st = strtotime($start);
        $en = strtotime($end);
        return date("H:i:s", mt_rand($st, $en));
    }
}