<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Lembur extends Auth_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->model(['Lembur_model', 'Pegawai_model', 'Divisi_model', 'Payroll_model', 'Shift_model']);
    }

    public function index()
    {
        $tahun = (int) ($this->input->get('tahun') ?: date('Y'));
        $bulan = str_pad((string) ((int) ($this->input->get('bulan') ?: date('m'))), 2, '0', STR_PAD_LEFT);
        $status = strtoupper((string) $this->input->get('status'));
        $id_divisi = $this->input->get('divisi');

        $data = [
            'page_title'    => 'Manajemen Lembur',
            'page_subtitle' => 'Kelola pengajuan lembur pegawai',
            'f_status'      => in_array($status, ['DRAFT', 'APPROVED', 'REJECTED'], TRUE) ? $status : '',
            'f_divisi'      => $id_divisi ? (int) $id_divisi : '',
            'f_tahun'       => $tahun,
            'f_bulan'       => $bulan,
            'divisi_list'   => $this->Divisi_model->get_all(),
        ];
        $this->render('transaksi/lembur/list', $data);
    }

    public function ajax_list()
    {
        $tahun = (int) ($this->input->get_post('tahun') ?: date('Y'));
        $bulan = (int) ($this->input->get_post('bulan') ?: date('m'));
        $status = strtoupper((string) $this->input->get_post('filter_status'));
        $id_divisi = $this->input->get_post('divisi') ? (int) $this->input->get_post('divisi') : NULL;
        $draw    = (int) $this->input->get_post('draw');
        $start   = (int) $this->input->get_post('start');
        $length  = (int) $this->input->get_post('length');
        $search  = trim((string) $this->input->get_post('search[value]', TRUE));
        $order_col = (int) $this->input->get_post('order[0][column]');
        $order_dir = (string) $this->input->get_post('order[0][dir]', TRUE);

        $total = $this->Lembur_model->datatable_total($tahun, $bulan, $id_divisi, $status);
        $filtered = $this->Lembur_model->datatable_filtered($tahun, $bulan, $id_divisi, $status, $search);
        $rows = $this->Lembur_model->datatable_data($tahun, $bulan, $start, $length, $order_col, $order_dir, $id_divisi, $status, $search);

        $data = [];
        foreach ($rows as $row) {
            $status_badge = 'badge-secondary';
            if ($row->status === 'DRAFT') $status_badge = 'badge-warning';
            elseif ($row->status === 'APPROVED') $status_badge = 'badge-success';
            elseif ($row->status === 'REJECTED') $status_badge = 'badge-danger';

            $aksi = '';
            if ($row->status === 'DRAFT') {
                $aksi .= '<a href="' . site_url('transaksi/lembur/edit/' . $row->id_lembur) . '" class="btn btn-xs btn-primary mr-1" title="Edit"><i class="fa fa-pencil"></i></a>';
                $aksi .= '<button type="button" class="btn btn-xs btn-success btn-approve mr-1" data-id="' . (int) $row->id_lembur . '" title="Setujui"><i class="fa fa-check"></i></button>';
                $aksi .= '<button type="button" class="btn btn-xs btn-warning btn-reject mr-1" data-id="' . (int) $row->id_lembur . '" title="Tolak"><i class="fa fa-times"></i></button>';
                $aksi .= '<button type="button" class="btn btn-xs btn-danger btn-confirm-delete" data-id="' . (int) $row->id_lembur . '" title="Hapus"><i class="fa fa-trash"></i></button>';
            } else {
                $aksi .= '<a href="' . site_url('transaksi/lembur/edit/' . $row->id_lembur) . '" class="btn btn-xs btn-info" title="Lihat"><i class="fa fa-eye"></i></a>';
            }

            $data[] = [
                'nip'         => html_escape($row->nip),
                'nama_lengkap'=> html_escape($row->nama_lengkap),
                'nama_divisi' => html_escape($row->nama_divisi),
                'tanggal'     => format_tanggal($row->tanggal),
                'jam_mulai'   => substr($row->jam_mulai, 0, 5),
                'jam_selesai' => substr($row->jam_selesai, 0, 5),
                'durasi_jam'  => '<strong>' . rtrim(rtrim((string) $row->durasi_jam, '0'), '.') . '</strong>',
                'alasan'      => html_escape(substr((string) $row->alasan, 0, 45)) . (strlen((string) $row->alasan) > 45 ? '...' : ''),
                'status'      => '<span class="badge ' . $status_badge . '">' . $row->status . '</span>',
                'aksi'        => $aksi,
            ];
        }

        echo json_encode([
            'draw'            => $draw,
            'recordsTotal'    => $total,
            'recordsFiltered' => $filtered,
            'data'            => $data,
        ]);
    }

    public function tambah()
    {
        $data = [
            'page_title'    => 'Tambah Pengajuan Lembur',
            'page_subtitle' => 'Buat pengajuan lembur baru',
            'pegawai_list'  => [],
            'row'           => NULL,
        ];
        $this->render('transaksi/lembur/form', $data);
    }

    public function edit($id)
    {
        $lembur = $this->Lembur_model->get_by_id((int) $id);
        if (!$lembur) {
            $this->session->set_flashdata('error', 'Data tidak ditemukan');
            redirect('transaksi/lembur');
        }

        $data = [
            'page_title'    => 'Edit Pengajuan Lembur',
            'page_subtitle' => 'Ubah data pengajuan',
            'pegawai_list'  => [],
            'row'           => $lembur,
        ];
        $this->render('transaksi/lembur/form', $data);
    }

    public function simpan()
    {
        if ($this->input->server('REQUEST_METHOD') !== 'POST') {
            redirect('transaksi/lembur');
        }

        $id = $this->input->post('id_lembur');
        $id_pegawai = (int) $this->input->post('id_pegawai');
        $jam_mulai = $this->input->post('jam_mulai');
        $jam_selesai = $this->input->post('jam_selesai');
        $tanggal = $this->input->post('tanggal');

        $pegawai = $this->Pegawai_model->get_by_id($id_pegawai);
        if (!$pegawai) {
            $this->session->set_flashdata('error', 'Pegawai tidak ditemukan. Pilih pegawai dari daftar autocomplete.');
            redirect('transaksi/lembur' . ($id ? '/edit/' . (int) $id : '/tambah'));
        }

        $validasi_jadwal = $this->_validate_jadwal_lembur($pegawai, $tanggal, $jam_mulai, $jam_selesai);
        if ($validasi_jadwal['ok'] !== TRUE) {
            $this->session->set_flashdata('error', $validasi_jadwal['message']);
            redirect('transaksi/lembur' . ($id ? '/edit/' . (int) $id : '/tambah'));
        }

        $durasi = $validasi_jadwal['durasi_jam'];

        $payload = [
            'id_pegawai'   => $id_pegawai,
            'tanggal'      => $tanggal,
            'jam_mulai'    => $jam_mulai,
            'jam_selesai'  => $jam_selesai,
            'durasi_jam'   => $durasi,
            'alasan'       => $this->input->post('alasan'),
            'status'       => 'DRAFT',
        ];

        if ($this->Payroll_model->has_locked_or_approved_period($payload['tanggal'], $payload['tanggal'])) {
            $this->session->set_flashdata('error', 'Periode payroll APPROVED/LOCKED tidak dapat diubah');
            redirect('transaksi/lembur');
        }

        if ($id) {
            $this->Lembur_model->update($id, $payload);
            audit_log('UPDATE', 'Lembur', "ID: $id | Durasi: " . $payload['durasi_jam'] . ' jam');
        } else {
            $this->Lembur_model->insert($payload);
            audit_log('INSERT', 'Lembur', 'Durasi: ' . $payload['durasi_jam'] . ' jam');
        }

        $this->session->set_flashdata('success', 'Data tersimpan');
        redirect('transaksi/lembur');
    }

    public function ajax_pegawai_search()
    {
        $this->output->set_content_type('application/json');
        $q = trim((string) $this->input->get('q', TRUE));
        if ($q === '' || strlen($q) < 2) {
            echo json_encode([]);
            return;
        }

        $this->db->select('id_pegawai, nip, nama_lengkap, id_divisi')
                 ->from('tb_pegawai')
                 ->where('status_pegawai', 'AKTIF')
                 ->group_start()
                 ->like('nip', $q, 'both')
                 ->or_like('nama_lengkap', $q, 'both')
                 ->group_end()
                 ->order_by('nama_lengkap', 'ASC')
                 ->limit(20);
        $rows = $this->db->get()->result();

        $result = [];
        foreach ($rows as $row) {
            $result[] = [
                'id_pegawai' => (int) $row->id_pegawai,
                'nip' => $row->nip,
                'nama_lengkap' => $row->nama_lengkap,
                'label' => $row->nip . ' - ' . $row->nama_lengkap,
            ];
        }

        echo json_encode($result);
    }

    public function approve($id)
    {
        header('Content-Type: application/json');
        $lembur = $this->Lembur_model->get_by_id((int) $id);
        if (!$lembur) {
            echo json_encode(['success' => FALSE, 'message' => 'Data tidak ditemukan']);
            exit;
        }

        if ($this->Payroll_model->has_locked_or_approved_period($lembur->tanggal, $lembur->tanggal)) {
            echo json_encode(['success' => FALSE, 'message' => 'Periode payroll APPROVED/LOCKED tidak dapat diubah']);
            exit;
        }

        $this->Lembur_model->approve($id, $this->session->userdata('id_user'));
        audit_log('APPROVE', 'Lembur', "ID: $id | Durasi: {$lembur->durasi_jam} jam");
        echo json_encode(['success' => TRUE, 'message' => 'Disetujui']);
    }

    public function reject($id)
    {
        header('Content-Type: application/json');
        $catatan = $this->input->post('catatan');
        $lembur = $this->Lembur_model->get_by_id((int) $id);
        if (!$lembur) {
            echo json_encode(['success' => FALSE, 'message' => 'Data tidak ditemukan']);
            exit;
        }

        if ($this->Payroll_model->has_locked_or_approved_period($lembur->tanggal, $lembur->tanggal)) {
            echo json_encode(['success' => FALSE, 'message' => 'Periode payroll APPROVED/LOCKED tidak dapat diubah']);
            exit;
        }

        $this->Lembur_model->reject($id, $catatan);
        audit_log('REJECT', 'Lembur', "ID: $id | Catatan: $catatan");
        echo json_encode(['success' => TRUE, 'message' => 'Ditolak']);
    }

    public function hapus($id)
    {
        $lembur = $this->Lembur_model->get_by_id((int) $id);
        if (!$lembur || $lembur->status !== 'DRAFT') {
            $this->session->set_flashdata('error', 'Hanya draft yang dapat dihapus');
            redirect('transaksi/lembur');
        }

        if ($this->Payroll_model->has_locked_or_approved_period($lembur->tanggal, $lembur->tanggal)) {
            $this->session->set_flashdata('error', 'Data pada periode payroll APPROVED/LOCKED tidak dapat dihapus');
            redirect('transaksi/lembur');
        }

        $this->Lembur_model->delete($id);
        audit_log('DELETE', 'Lembur', "ID: $id");
        $this->session->set_flashdata('success', 'Data dihapus');
        redirect('transaksi/lembur');
    }

    /**
     * Bulk approve: POST JSON { "ids": [1, 2, 3] }
     */
    public function bulk_approve()
    {
        if (!$this->input->is_ajax_request()) {
            show_404();
        }

        $ids = json_decode($this->input->raw_input_stream, TRUE)['ids'] ?? [];
        if (empty($ids) || !is_array($ids)) {
            echo json_encode(['success' => FALSE, 'msg' => 'Tidak ada ID yang dikirim']);
            exit;
        }

        $id_user = $this->session->userdata('id_user');
        $jumlah  = $this->Lembur_model->bulk_approve($ids, $id_user);

        audit_log('BULK_APPROVE', 'Lembur', "$jumlah record di-approve sekaligus");
        echo json_encode(['success' => TRUE, 'msg' => "$jumlah record berhasil di-approve", 'jumlah' => $jumlah]);
    }

    /**
     * Bulk reject: POST JSON { "ids": [1, 2, 3], "catatan": "..." }
     */
    public function bulk_reject()
    {
        if (!$this->input->is_ajax_request()) {
            show_404();
        }

        $body    = json_decode($this->input->raw_input_stream, TRUE);
        $ids     = $body['ids'] ?? [];
        $catatan = $body['catatan'] ?? 'Bulk reject';

        if (empty($ids) || !is_array($ids)) {
            echo json_encode(['success' => FALSE, 'msg' => 'Tidak ada ID yang dikirim']);
            exit;
        }

        $jumlah = $this->Lembur_model->bulk_reject($ids, $catatan);

        audit_log('BULK_REJECT', 'Lembur', "$jumlah record di-reject sekaligus");
        echo json_encode(['success' => TRUE, 'msg' => "$jumlah record berhasil di-reject", 'jumlah' => $jumlah]);
    }

    private function _validate_jadwal_lembur($pegawai, $tanggal, $jam_mulai, $jam_selesai)
    {
        if (empty($tanggal) || empty($jam_mulai) || empty($jam_selesai)) {
            return ['ok' => FALSE, 'message' => 'Tanggal, jam mulai, dan jam selesai wajib diisi.'];
        }

        $schedule = $this->Shift_model->get_schedule_for_pegawai((int) $pegawai->id_pegawai, (int) $pegawai->id_divisi, $tanggal);
        if (!$schedule || (int) $schedule->is_hari_kerja !== 1 || empty($schedule->id_shift)) {
            return ['ok' => FALSE, 'message' => 'Gagal simpan: tanggal tersebut bukan hari kerja atau jadwal shift pegawai belum ditetapkan.'];
        }

        $mulaiTs = strtotime($tanggal . ' ' . $jam_mulai);
        $selesaiTs = strtotime($tanggal . ' ' . $jam_selesai);
        if ($selesaiTs <= $mulaiTs) {
            $selesaiTs += 86400;
        }

        $shiftMulaiTs = strtotime($tanggal . ' ' . $schedule->jam_masuk);
        $shiftSelesaiTs = strtotime($tanggal . ' ' . $schedule->jam_keluar);
        if ((int) ($schedule->lintas_tengah_malam ?? 0) === 1 || $shiftSelesaiTs <= $shiftMulaiTs) {
            $shiftSelesaiTs += 86400;
        }

        if ($mulaiTs < $shiftSelesaiTs) {
            return [
                'ok' => FALSE,
                'message' => 'Gagal simpan: lembur harus dimulai setelah jam pulang shift (' . substr((string) $schedule->jam_keluar, 0, 5) . ').'
            ];
        }

        $durasi = round(($selesaiTs - $mulaiTs) / 3600, 2);
        if ($durasi < 0.5) {
            return ['ok' => FALSE, 'message' => 'Gagal simpan: durasi lembur minimal 0.5 jam.'];
        }

        return ['ok' => TRUE, 'durasi_jam' => $durasi];
    }
}
