<?php

namespace App\Controllers;

class Pwa extends BaseController
{
    protected $db;

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

    public function index()
    {
        $id_pegawai = session()->get('id_pegawai');
        $tanggal_hari_ini = date('Y-m-d');
        $nama_hari_indo = $this->get_nama_hari(date('D'));

        // 1. AMBIL DATA PEGAWAI & OPD (Untuk ambil id_jam_kerja di OPD)
        $pegawai = $this->db->table('pegawai')
            ->select('pegawai.*, opd.id_jam_kerja as id_jam_opd')
            ->join('opd', 'pegawai.id_opd = opd.id_opd', 'left')
            ->where('id_pegawai', $id_pegawai)
            ->get()->getRowArray();

        // 2. LOGIKA PENENTUAN JADWAL HARI INI (Agar muncul di Dashboard HP)
        $cek_plotting = $this->db->table('plotting_shift')
            ->where(['id_pegawai' => $id_pegawai, 'tanggal' => $tanggal_hari_ini])
            ->get()->getRow();

        if ($cek_plotting) {
            $id_final_jam = $cek_plotting->id_jam_kerja;
        } else {
            $id_final_jam = ($pegawai['id_jam_opd']) ? $pegawai['id_jam_opd'] : 1; // Fallback ID 1
        }

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

        // 3. DATA LIBUR & ABSEN HARI INI
        $libur = $this->db->table('hari_libur')->where('tanggal', $tanggal_hari_ini)->get()->getRowArray();
        $libur_mendatang = $this->db->table('hari_libur')->where('tanggal >', $tanggal_hari_ini)->limit(5)->get()->getResultArray();
        $terakhir = $this->db->table('presensi')->where('id_pegawai', $id_pegawai)->where('tanggal', $tanggal_hari_ini)->get()->getRowArray();

        // 4. LOGIKA RIWAYAT (YANG TADI HILANG)
        $filter_bulan = $this->request->getGet('bulan');
        $filter_tahun = $this->request->getGet('tahun');

        $builder = $this->db->table('presensi')->where('id_pegawai', $id_pegawai);

        if ($filter_bulan && $filter_tahun) {
            $builder->where('MONTH(tanggal)', $filter_bulan)->where('YEAR(tanggal)', $filter_tahun);
        } else {
            $builder->limit(10); // Tampilkan 10 riwayat terakhir jika tanpa filter
        }

        $riwayat = $builder->orderBy('tanggal', 'DESC')->get()->getResultArray();

        // 5. KIRIM SEMUA KE VIEW
        return view('pwa/index', [
            'pegawai'         => $pegawai,
            'jadwal_hari_ini' => $jadwal_hari_ini,
            'libur'           => $libur,
            'libur_mendatang' => $libur_mendatang,
            'terakhir'        => $terakhir,
            'riwayat'         => $riwayat, // Pastikan variabel ini ada
            'bulan_aktif'     => $filter_bulan,
            'tahun_aktif'     => $filter_tahun,
            'face_data'       => $pegawai['face_vector'] ?? null
        ]);
    }

    public function submit_absen()
{
    // 1. Inisialisasi Data Dasar
    $id_pegawai  = session()->get('id_pegawai');
    $lat_user    = $this->request->getPost('latitude');
    $lng_user    = $this->request->getPost('longitude');
    $device_info = $this->request->getPost('device_info');
    $nip_user    = $this->request->getPost('nip');

    $tanggal      = date('Y-m-d');
    $jam_sekarang = date('H:i:s');
    $nama_hari_indo = $this->get_nama_hari(date('D'));

    // ============================================================
    // D2. IMPOSSIBLE SPEED (Detection 2 - Anti Teleport)
    // ============================================================
    $last_logs = $this->db->table('presensi')
        ->where('id_pegawai', $id_pegawai)
        ->orderBy('created_at', 'DESC')
        ->limit(1)
        ->get()->getRow();

    if ($last_logs) {
        $jarak_km = $this->hitung_jarak($lat_user, $lng_user, $last_logs->latitude, $last_logs->longitude) / 1000;
        $waktu_jam = (strtotime(date('Y-m-d H:i:s')) - strtotime($last_logs->created_at)) / 3600;

        if ($waktu_jam > 0) {
            $kecepatan = $jarak_km / $waktu_jam;
            // Jika pindah lokasi dengan kecepatan > 150km/jam, indikasi Fake GPS
            if ($kecepatan > 150 && $jarak_km > 1) {
                return $this->response->setJSON(['status' => 'error', 'message' => 'Deteksi perpindahan lokasi tidak wajar (Teleportasi).']);
            }
        }
    }

    // ============================================================
    // A. PENENTUAN JADWAL (HIRARKI: PLOTTING > OPD > GLOBAL)
    // ============================================================
    
    // Cek Prioritas 1: Plotting Shift
    $plotting = $this->db->table('plotting_shift')
        ->where(['id_pegawai' => $id_pegawai, 'tanggal' => $tanggal])
        ->get()->getRow();

    if ($plotting) {
        $id_final_jam = $plotting->id_jam_kerja;
    } else {
        // Prioritas 2: Ambil Jadwal dari Tabel OPD
        $pegawai = $this->db->table('pegawai')
            ->select('pegawai.id_opd, opd.id_jam_kerja as jam_opd')
            ->join('opd', 'pegawai.id_opd = opd.id_opd', 'left')
            ->where('pegawai.id_pegawai', $id_pegawai)
            ->get()->getRow();
        
        // Gunakan ID Jam Kerja OPD, jika di OPD kosong, fallback ke ID 1 (Reguler)
        $id_final_jam = ($pegawai && $pegawai->jam_opd) ? $pegawai->jam_opd : 1; 
    }

    // Ambil Detail Jam (Masuk, Pulang, Toleransi) berdasarkan Hari
    $jadwal = $this->db->table('jam_kerja_detail')
        ->where(['id_jam_kerja' => $id_final_jam, 'hari' => $nama_hari_indo])
        ->get()->getRowArray();

    if (!$jadwal) {
        return $this->response->setJSON(['status' => 'error', 'message' => "Hari ini ($nama_hari_indo) bukan hari kerja Anda."]);
    }

    $jam_masuk_target  = $jadwal['jam_masuk'];
    $jam_pulang_target = $jadwal['jam_pulang'];
    $toleransi         = $jadwal['toleransi_menit'];

    // ============================================================
    // B. VALIDASI RADIUS (MULTI-LOKASI OPD)
    // ============================================================
    $id_opd_final  = ($plotting) ? $this->get_opd_by_pegawai($id_pegawai) : $pegawai->id_opd;
    $daftar_lokasi = $this->db->table('opd_lokasi')->where('id_opd', $id_opd_final)->get()->getResultArray();

    $is_dalam_radius = false;
    $nama_lokasi_absen = "";

    foreach ($daftar_lokasi as $lok) {
        $jarak = $this->hitung_jarak($lat_user, $lng_user, $lok['latitude'], $lok['longitude']);
        if ($jarak <= $lok['radius_meter']) {
            $is_dalam_radius = true;
            $nama_lokasi_absen = $lok['nama_lokasi'];
            break;
        }
    }

    if (!$is_dalam_radius) {
        return $this->response->setJSON(['status' => 'error', 'message' => 'Anda berada di luar radius kantor!']);
    }

    // ============================================================
    // C. EKSEKUSI PRESENSI (MASUK ATAU PULANG)
    // ============================================================
    $cek = $this->db->table('presensi')->where(['id_pegawai' => $id_pegawai, 'tanggal' => $tanggal])->get()->getRowArray();

    if (!$cek) {
        // --- PROSES ABSEN MASUK ---
        $batas_masuk = date('H:i:s', strtotime($jam_masuk_target . " + $toleransi minutes"));
        $status_masuk = ($jam_sekarang > $batas_masuk) ? 'Terlambat' : 'Tepat Waktu';
        $menit_telat  = ($status_masuk == 'Terlambat') ? floor((strtotime($jam_sekarang) - strtotime($jam_masuk_target)) / 60) : 0;

        $this->db->table('presensi')->insert([
            'id_pegawai'            => $id_pegawai,
            'id_jam_kerja_snapshot' => $id_final_jam,
            'tanggal'               => $tanggal,
            'jam_masuk_aktual'      => $jam_sekarang,
            'jam_masuk_seharusnya'  => $jam_masuk_target,
            'jam_pulang_seharusnya' => $jam_pulang_target,
            'menit_keterlambatan'   => $menit_telat,
            'status_masuk'          => $status_masuk,
            'latitude'              => $lat_user,
            'longitude'             => $lng_user,
            'device_info'           => $device_info,
            'nip'                   => $nip_user,
            'kategori'              => 'Hadir',
            'created_at'            => date('Y-m-d H:i:s')
        ]);

        return $this->response->setJSON(['status' => 'success', 'message' => "Absen Masuk Berhasil di $nama_lokasi_absen!"]);

    } else {
        // --- PROSES ABSEN PULANG ---



        // 2. Kunci Jeda Waktu (Mencegah Double Tap / Klik Cepat 2x)
        // Pegawai baru bisa pulang minimal 5 menit setelah masuk
        $selisih_menit = (strtotime($jam_sekarang) - strtotime($cek['jam_masuk_aktual'])) / 60;
        if ($selisih_menit < 5) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Gagal. Beri jeda minimal 5 menit dari absen masuk.']);
        }

        $status_pulang = ($jam_sekarang < $jam_pulang_target) ? 'Cepat Pulang' : 'Selesai';

        $this->db->table('presensi')->where('id_presensi', $cek['id_presensi'])->update([
            'jam_pulang_aktual' => $jam_sekarang,
            'status_pulang'     => $status_pulang,
            'updated_at'        => date('Y-m-d H:i:s')
        ]);

        return $this->response->setJSON(['status' => 'success', 'message' => "Absen Pulang Berhasil!"]);
    }
}



    private function hitung_jarak($lat1, $lon1, $lat2, $lon2)
    {
        $theta = $lon1 - $lon2;
        $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
        $dist = acos($dist);
        $dist = rad2deg($dist);
        return $dist * 60 * 1.1515 * 1609.344;
    }

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

    public function submit_izin()
    {
        $id_pegawai = session()->get('id_pegawai');
        $kategori   = $this->request->getPost('kategori');
        $deskripsi  = $this->request->getPost('deskripsi');
        $file       = $this->request->getFile('file_bukti');
        $tanggal    = date('Y-m-d');

        if ($file && $file->isValid() && !$file->hasMoved()) {
            $newName = $file->getRandomName();
            $file->move(FCPATH . 'uploads/bukti/', $newName);

            // --- LOGIKA CEK DATA HARI INI ---
            $cek = $this->db->table('presensi')
                ->where(['id_pegawai' => $id_pegawai, 'tanggal' => $tanggal])
                ->get()->getRow();

            $data = [
                'kategori'     => $kategori,
                'deskripsi'    => $deskripsi,
                'file_bukti'   => $newName,
                'status_masuk' => 'Pending',
                'updated_at'   => date('Y-m-d H:i:s')
            ];

            if ($cek) {
                // Jika sudah ada baris absen hari ini, kita UPDATE baris tersebut
                $this->db->table('presensi')
                    ->where('id_presensi', $cek->id_presensi)
                    ->update($data);
                $msg = "Pengajuan $kategori berhasil diperbarui.";
            } else {
                // Jika benar-benar belum ada data hari ini, baru INSERT
                $data['id_pegawai'] = $id_pegawai;
                $data['tanggal']    = $tanggal;
                $data['created_at'] = date('Y-m-d H:i:s');
                $this->db->table('presensi')->insert($data);
                $msg = "Pengajuan $kategori berhasil dikirim.";
            }

            return $this->response->setJSON(['status' => 'success', 'message' => $msg]);
        }
        return $this->response->setJSON(['status' => 'error', 'message' => 'Gagal unggah file.']);
    }
}
