<?php

namespace App\Controllers;

use CodeIgniter\Controller;

class Plotting 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 = session()->get('id_opd');

        // Builder Pegawai & OPD untuk keperluan Modal Form
        $builder_pegawai = $this->db->table('pegawai')->orderBy('nama_lengkap', 'ASC');
        $builder_opd     = $this->db->table('opd')->orderBy('nama_opd', 'ASC');

        // FILTER: Jika bukan Superadmin, hanya tampilkan data milik OPD-nya sendiri
        if (!in_array($level, ['Superadmin', 'kabupaten'])) {
            $builder_pegawai->where('id_opd', $id_opd);
            $builder_opd->where('id_opd', $id_opd);
        }

        $data = [
            'level'     => $level,
            'pegawai'   => $builder_pegawai->get()->getResultArray(),
            'opd'       => $builder_opd->get()->getResultArray(),
            'jam_kerja' => $this->db->table('jam_kerja')->where('tipe_jadwal', 'Shift')->get()->getResultArray()
        ];

        return view('plotting/index', $data);
    }

    // ========================================================================
    // FUNGSI SERVER-SIDE DATATABLES UNTUK LOAD DATA CEPAT BERPROGRESS
    // ========================================================================
    public function ajax_list()
    {
        try {
            $level   = session()->get('level');
            $id_opd  = session()->get('id_opd');

            // Parameter DataTables (Amankan dari Null / PHP 8 Array Offset Error)
            $start  = intval($this->request->getPost('start') ?? 0);
            $length = intval($this->request->getPost('length') ?? 10);

            $postSearch = $this->request->getPost('search');
            $search = (is_array($postSearch) && isset($postSearch['value'])) ? $postSearch['value'] : '';

            $draw   = intval($this->request->getPost('draw') ?? 1);

            // Builder Utama
            $builder = $this->db->table('plotting_shift ps')
                ->select('ps.id_plotting, ps.tanggal, p.nama_lengkap, jk.nama_jadwal')
                ->join('pegawai p', 'ps.id_pegawai = p.id_pegawai', 'left')
                ->join('jam_kerja jk', 'ps.id_jam_kerja = jk.id_jam_kerja', 'left');

            // Filter OPD Level
            if (!in_array($level, ['Superadmin', 'kabupaten'])) {
                $builder->where('p.id_opd', $id_opd);
            }

            // Pencarian (Search)
            if (!empty($search)) {
                $builder->groupStart()
                    ->like('p.nama_lengkap', $search)
                    ->orLike('jk.nama_jadwal', $search)
                    ->orLike('ps.tanggal', $search)
                    ->groupEnd();
            }

            // Dapatkan Total Filtered Data (sebelum limit)
            $recordsFiltered = $builder->countAllResults(false);

            // Sorting & Limit
            $builder->orderBy('ps.tanggal', 'DESC');
            if ($length != -1) {
                $builder->limit($length, $start);
            }
            $query = $builder->get()->getResult();

            // Hitung Total Seluruh Data (Tanpa Filter)
            $builderTotal = $this->db->table('plotting_shift ps')
                ->join('pegawai p', 'ps.id_pegawai = p.id_pegawai', 'left');
            if (!in_array($level, ['Superadmin', 'kabupaten'])) {
                $builderTotal->where('p.id_opd', $id_opd);
            }
            $recordsTotal = $builderTotal->countAllResults();

            // Format data untuk output JSON DataTables
            $data = [];
            foreach ($query as $r) {
                // Perhatikan tombol hapus sekarang menggunakan fungsi JS onclick yang sudah kita buat
                $btnHapus = '<button type="button" class="btn btn-sm btn-light border text-danger shadow-sm" onclick="hapusPlotting(' . $r->id_plotting . ')"><i class="fas fa-trash"></i></button>';

                $data[] = [
                    '<span class="ps-4 small">' . date('d/m/Y', strtotime($r->tanggal)) . '</span>',
                    '<div class="fw-bold small text-dark">' . $r->nama_lengkap . '</div>',
                    '<span class="badge bg-info-subtle text-info border border-info-subtle">' . $r->nama_jadwal . '</span>',
                    '<div class="text-center">' . $btnHapus . '</div>'
                ];
            }

            // Kembalikan Response JSON yang valid
            $output = [
                "draw"            => $draw,
                "recordsTotal"    => $recordsTotal,
                "recordsFiltered" => $recordsFiltered,
                "data"            => $data
            ];

            return $this->response->setJSON($output);
        } catch (\Exception $e) {
            // Jika ada error (misal salah nama kolom di DB), DataTables akan menampilkan pesan errornya, bukan blank/crash.
            return $this->response->setJSON([
                "draw"            => intval($this->request->getPost('draw') ?? 1),
                "recordsTotal"    => 0,
                "recordsFiltered" => 0,
                "data"            => [],
                "error"           => "Server Error: " . $e->getMessage()
            ]);
        }
    }

    public function simpan()
    {
        $data = [
            'id_pegawai'   => $this->request->getPost('id_pegawai'),
            'id_jam_kerja' => $this->request->getPost('id_jam_kerja'),
            'tanggal'      => $this->request->getPost('tanggal'),
        ];

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

        if ($cek) {
            $this->db->table('plotting_shift')->where('id_plotting', $cek->id_plotting)->update($data);
            $msg = 'Jadwal berhasil diperbarui.';
        } else {
            $this->db->table('plotting_shift')->insert($data);
            $msg = 'Jadwal shift berhasil ditambahkan.';
        }

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

    public function simpan_massal()
    {
        ini_set('memory_limit', '512M');
        set_time_limit(0);

        $scope          = $this->request->getPost('scope');
        $id_opd         = $this->request->getPost('id_opd');
        $target_pegawai = $this->request->getPost('target_pegawai');
        $id_jam_kerja   = $this->request->getPost('id_jam_kerja');

        // ============================================================
        // 1. LOGIKA PENENTUAN TANGGAL (RANGE vs MULTIPLE)
        // ============================================================
        $tipe_tanggal = $this->request->getPost('tipe_tanggal') ?? 'range';
        $dates_to_process = [];

        if ($tipe_tanggal == 'range') {
            $tgl_mulai   = $this->request->getPost('tgl_mulai');
            $tgl_selesai = $this->request->getPost('tgl_selesai');
            if ($tgl_mulai > $tgl_selesai) return $this->response->setJSON(['status' => 'error', 'message' => 'Rentang tanggal error.']);

            $begin = new \DateTime($tgl_mulai);
            $end   = new \DateTime($tgl_selesai);
            $end   = $end->modify('+1 day');
            $interval  = new \DateInterval('P1D');
            $daterange = new \DatePeriod($begin, $interval, $end);

            foreach ($daterange as $date) {
                $dates_to_process[] = $date->format('Y-m-d');
            }
        } else {
            // Tipe Multiple (Banyak Tanggal Acak)
            $tanggal_multiple = $this->request->getPost('tanggal_multiple');
            if (empty($tanggal_multiple)) return $this->response->setJSON(['status' => 'error', 'message' => 'Pilih minimal satu tanggal.']);

            // Flatpickr memisahkan tanggal dengan koma dan spasi ", "
            $raw_dates = explode(',', $tanggal_multiple);
            foreach ($raw_dates as $rd) {
                $dates_to_process[] = trim($rd);
            }
        }

        // ============================================================
        // 2. AMBIL DATA PEGAWAI
        // ============================================================
        $builder = $this->db->table('pegawai')->select('id_pegawai');

        if (!in_array(session()->get('level'), ['Superadmin', 'kabupaten'])) {
            $builder->where('id_opd', session()->get('id_opd'));
        }

        $list_pegawai = [];

        if ($scope == 'global') {
            $list_pegawai = $builder->get()->getResultArray();
        } elseif ($scope == 'opd') {
            if (empty($id_opd)) return $this->response->setJSON(['status' => 'error', 'message' => 'Pilih OPD.']);
            $list_pegawai = $builder->where('id_opd', $id_opd)->get()->getResultArray();
        } elseif ($scope == 'pegawai') {
            if (empty($target_pegawai) || !is_array($target_pegawai)) return $this->response->setJSON(['status' => 'error', 'message' => 'Pilih minimal satu pegawai.']);
            foreach ($target_pegawai as $id_peg) {
                $list_pegawai[] = ['id_pegawai' => $id_peg];
            }
        }

        if (empty($list_pegawai)) return $this->response->setJSON(['status' => 'error', 'message' => 'Pegawai tidak ditemukan.']);

        // ============================================================
        // 3. PROSES INSERT BATCH & HAPUS JADWAL LAMA
        // ============================================================
        $this->db->transStart();

        $batchSize = 1000;
        $data_batch = [];
        $total_terproses = 0;

        foreach ($list_pegawai as $peg) {

            // A. HAPUS DULU DATA LAMA DI TANGGAL-TANGGAL YANG TERPILIH
            $this->db->table('plotting_shift')
                ->where('id_pegawai', $peg['id_pegawai'])
                ->whereIn('tanggal', $dates_to_process)
                ->delete();

            // B. SIAPKAN DATA BARU
            foreach ($dates_to_process as $tgl_plot) {
                $data_batch[] = [
                    'id_pegawai'   => $peg['id_pegawai'],
                    'id_jam_kerja' => $id_jam_kerja,
                    'tanggal'      => $tgl_plot
                ];

                // C. CEK MUATAN BATCH
                if (count($data_batch) >= $batchSize) {
                    $this->db->table('plotting_shift')->insertBatch($data_batch);
                    $total_terproses += count($data_batch);
                    $data_batch = [];
                }
            }
        }

        // D. SIMPAN SISA DATA
        if (!empty($data_batch)) {
            $this->db->table('plotting_shift')->insertBatch($data_batch);
            $total_terproses += count($data_batch);
        }

        $this->db->transComplete();

        if ($this->db->transStatus() === FALSE) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Gagal menyimpan (Rollback terjadi).']);
        }

        return $this->response->setJSON(['status' => 'success', 'message' => "Plotting Massal Sukses! Total $total_terproses jadwal dibuat."]);
    }

    public function hapus($id)
    {
        $this->db->table('plotting_shift')->where('id_plotting', $id)->delete();
        return $this->response->setJSON(['status' => 'success', 'message' => 'Jadwal shift berhasil dihapus.']);
    }

    public function hapus_massal()
    {
        $scope          = $this->request->getPost('scope_hapus');
        $id_opd         = $this->request->getPost('id_opd_hapus');
        $target_pegawai = $this->request->getPost('target_pegawai_hapus'); // Array
        $tgl_mulai      = $this->request->getPost('tgl_mulai_hapus');
        $tgl_selesai    = $this->request->getPost('tgl_selesai_hapus');

        if ($tgl_mulai > $tgl_selesai) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Rentang tanggal tidak valid.']);
        }

        $builder = $this->db->table('plotting_shift');

        // PROTEKSI: Jika bukan Superadmin, paksa scope ke OPD-nya sendiri
        if (!in_array(session()->get('level'), ['Superadmin', 'kabupaten'])) {
            $subQuery = $this->db->table('pegawai')->select('id_pegawai')->where('id_opd', session()->get('id_opd'))->get()->getResultArray();
            $ids = array_column($subQuery, 'id_pegawai');
            if (empty($ids)) return $this->response->setJSON(['status' => 'error', 'message' => 'Tidak ada data pegawai di OPD Anda.']);
            $builder->whereIn('id_pegawai', $ids);
        }

        // Filter berdasarkan Scope
        if ($scope == 'opd') {
            if (empty($id_opd)) return $this->response->setJSON(['status' => 'error', 'message' => 'Pilih OPD yang akan dihapus.']);
            $subQuery = $this->db->table('pegawai')->select('id_pegawai')->where('id_opd', $id_opd)->get()->getResultArray();
            $ids = array_column($subQuery, 'id_pegawai');
            if (empty($ids)) return $this->response->setJSON(['status' => 'error', 'message' => 'Tidak ada data pegawai di OPD tersebut.']);
            $builder->whereIn('id_pegawai', $ids);
        } elseif ($scope == 'pegawai') {
            if (empty($target_pegawai) || !is_array($target_pegawai)) return $this->response->setJSON(['status' => 'error', 'message' => 'Pilih minimal satu pegawai.']);
            $builder->whereIn('id_pegawai', $target_pegawai);
        }

        // Filter Tanggal
        $builder->where('tanggal >=', $tgl_mulai);
        $builder->where('tanggal <=', $tgl_selesai);

        $builder->delete();

        return $this->response->setJSON(['status' => 'success', 'message' => 'Pembersihan jadwal massal berhasil dilakukan.']);
    }
}
