<?php

namespace App\Controllers;

use CodeIgniter\Controller;

class Plotting extends BaseController
{
    protected $db;

    public function __construct()
    {
        $this->db = \Config\Database::connect();
    }

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

        // Builder Pegawai & OPD
        $builder_pegawai = $this->db->table('pegawai')->orderBy('nama_lengkap', 'ASC');
        $builder_opd     = $this->db->table('opd')->orderBy('nama_opd', 'ASC');
        $builder_plot    = $this->db->table('plotting_shift')
            ->select('plotting_shift.*, pegawai.nama_lengkap, jam_kerja.nama_jadwal')
            ->join('pegawai', 'plotting_shift.id_pegawai = pegawai.id_pegawai')
            ->join('jam_kerja', 'plotting_shift.id_jam_kerja = jam_kerja.id_jam_kerja')
            ->orderBy('plotting_shift.tanggal', 'DESC');

        // 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);
            $builder_plot->where('pegawai.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(),
            'plotting'  => $builder_plot->get()->getResultArray()
        ];

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

    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 redirect()->to('plotting')->with('success', $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 redirect()->back()->with('error', '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 redirect()->back()->with('error', '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 redirect()->back()->with('error', 'Pilih OPD.');
            $list_pegawai = $builder->where('id_opd', $id_opd)->get()->getResultArray();
        } elseif ($scope == 'pegawai') {
            if (empty($target_pegawai)) return redirect()->back()->with('error', 'Pilih minimal satu pegawai.');
            foreach($target_pegawai as $id_peg) {
                $list_pegawai[] = ['id_pegawai' => $id_peg];
            }
        }

        if (empty($list_pegawai)) return redirect()->back()->with('error', '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 redirect()->back()->with('error', 'Gagal menyimpan (Rollback terjadi).');
        }

        return redirect()->to('plotting')->with('success', "Plotting Massal Sukses! Total $total_terproses jadwal dibuat.");
    }

    public function hapus($id)
    {
        $this->db->table('plotting_shift')->where('id_plotting', $id)->delete();
        return redirect()->to('plotting')->with('success', '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 redirect()->back()->with('error', '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 redirect()->back()->with('error', 'Tidak ada data pegawai di OPD Anda.');
            $builder->whereIn('id_pegawai', $ids);
        }

        // Filter berdasarkan Scope
        if ($scope == 'opd') {
            if (empty($id_opd)) return redirect()->back()->with('error', '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 redirect()->back()->with('error', 'Tidak ada data pegawai di OPD tersebut.');
            $builder->whereIn('id_pegawai', $ids);
        } elseif ($scope == 'pegawai') {
            if (empty($target_pegawai)) return redirect()->back()->with('error', '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 redirect()->to('plotting')->with('success', 'Pembersihan jadwal massal berhasil dilakukan.');
    }
}