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

class Harilibur extends Auth_Controller
{
    private const HOLIDAY_SYNC_SOURCES = [
        'https://raw.githubusercontent.com/guangrei/APIHariLibur_V2/main/calendar.json',
        'https://raw.githubusercontent.com/guangrei/APIHariLibur_V2/main/holidays.json',
    ];

    public function __construct()
    {
        parent::__construct();
        $this->load->model('HariLibur_model');
    }

    public function index()
    {
        $tahun      = (int) ($this->input->get('tahun') ?: date('Y'));
        $tahun_list = $this->HariLibur_model->get_tahun_list();
        if (!in_array(date('Y'), $tahun_list)) array_unshift($tahun_list, (int) date('Y'));

        $data = [
            'page_title'    => 'Hari Libur & Kalender Kerja',
            'page_subtitle' => 'Kelola hari libur nasional dan perusahaan',
            'list'          => $this->HariLibur_model->get_all($tahun),
            'tahun'         => $tahun,
            'tahun_list'    => $tahun_list,
        ];
        $this->render('master/harlibur/list', $data);
    }

    public function tambah()
    {
        $this->_set_rules();
        if ($this->form_validation->run() === FALSE) {
            $this->render('master/harlibur/form', $this->_form_data());
            return;
        }

        $payload = $this->_payload();
        if ($this->HariLibur_model->tanggal_exists($payload['tanggal'])) {
            $this->session->set_flashdata('error', 'Tanggal ' . tgl_indonesia($payload['tanggal']) . ' sudah terdaftar sebagai hari libur.');
            $this->render('master/harlibur/form', $this->_form_data());
            return;
        }

        $this->HariLibur_model->insert($payload);
        audit_log('TAMBAH', 'Hari Libur', $payload['nama_libur'] . ' (' . $payload['tanggal'] . ')');
        $this->session->set_flashdata('success', 'Hari libur berhasil ditambahkan.');
        redirect('master/harlibur');
    }

    public function events_json()
    {
        $this->output->set_content_type('application/json');
        $tahun = (int) ($this->input->get('tahun') ?: date('Y'));
        $rows = $this->HariLibur_model->get_all($tahun);

        $events = [];
        foreach ($rows as $row) {
            $isNasional = ((string) $row->jenis === 'NASIONAL');
            $events[] = [
                'id' => (int) $row->id_libur,
                'title' => $row->nama_libur,
                'start' => $row->tanggal,
                'allDay' => TRUE,
                'backgroundColor' => $isNasional ? '#dc3545' : '#f0ad4e',
                'borderColor' => $isNasional ? '#dc3545' : '#f0ad4e',
                'textColor' => '#ffffff',
                'extendedProps' => [
                    'jenis' => $row->jenis,
                    'nama_libur' => $row->nama_libur,
                    'tanggal' => $row->tanggal,
                ],
            ];
        }

        echo json_encode($events);
    }

    public function save_ajax()
    {
        $this->output->set_content_type('application/json');

        if ($this->input->server('REQUEST_METHOD') !== 'POST') {
            echo json_encode(['success' => FALSE, 'message' => 'Metode request tidak valid.']);
            return;
        }

        $id = (int) $this->input->post('id_libur');
        $payload = $this->_payload();

        if (empty($payload['tanggal']) || empty($payload['nama_libur']) || !in_array($payload['jenis'], ['NASIONAL', 'PERUSAHAAN'], TRUE)) {
            echo json_encode(['success' => FALSE, 'message' => 'Tanggal, nama hari libur, dan jenis wajib diisi.']);
            return;
        }

        if ($this->HariLibur_model->tanggal_exists($payload['tanggal'], $id ?: NULL)) {
            echo json_encode(['success' => FALSE, 'message' => 'Tanggal tersebut sudah terdaftar sebagai hari libur lain.']);
            return;
        }

        if ($id > 0) {
            $row = $this->HariLibur_model->get_by_id($id);
            if (!$row) {
                echo json_encode(['success' => FALSE, 'message' => 'Data hari libur tidak ditemukan.']);
                return;
            }
            $this->HariLibur_model->update($id, $payload);
            audit_log('EDIT', 'Hari Libur', $payload['nama_libur'] . ' (' . $payload['tanggal'] . ')');
            $id_libur = $id;
            $message = 'Hari libur berhasil diperbarui.';
        } else {
            $id_libur = $this->HariLibur_model->insert($payload);
            audit_log('TAMBAH', 'Hari Libur', $payload['nama_libur'] . ' (' . $payload['tanggal'] . ')');
            $message = 'Hari libur berhasil ditambahkan.';
        }

        echo json_encode([
            'success' => TRUE,
            'message' => $message,
            'data' => [
                'id_libur' => (int) $id_libur,
                'tanggal' => $payload['tanggal'],
                'nama_libur' => $payload['nama_libur'],
                'jenis' => $payload['jenis'],
            ],
        ]);
    }

    public function delete_ajax($id)
    {
        $this->output->set_content_type('application/json');

        if ($this->input->server('REQUEST_METHOD') !== 'POST') {
            echo json_encode(['success' => FALSE, 'message' => 'Metode request tidak valid.']);
            return;
        }

        $row = $this->HariLibur_model->get_by_id((int) $id);
        if (!$row) {
            echo json_encode(['success' => FALSE, 'message' => 'Data hari libur tidak ditemukan.']);
            return;
        }

        $this->HariLibur_model->delete((int) $id);
        audit_log('HAPUS', 'Hari Libur', $row->nama_libur . ' (' . $row->tanggal . ')');

        echo json_encode(['success' => TRUE, 'message' => 'Hari libur berhasil dihapus.']);
    }

    public function sync_nasional()
    {
        $this->output->set_content_type('application/json');

        if ($this->input->server('REQUEST_METHOD') !== 'POST') {
            echo json_encode(['success' => FALSE, 'message' => 'Metode request tidak valid.']);
            return;
        }

        $tahun = (int) ($this->input->post('tahun') ?: date('Y'));
        if ($tahun < 2000 || $tahun > 2100) {
            echo json_encode(['success' => FALSE, 'message' => 'Tahun sinkron tidak valid.']);
            return;
        }

        $items = $this->_fetch_national_holidays($tahun);
        if (empty($items)) {
            echo json_encode(['success' => FALSE, 'message' => 'Gagal mengambil data hari libur nasional dari sumber sinkron.']);
            return;
        }

        $sync = $this->HariLibur_model->sync_nasional_batch($items);
        audit_log('SYNC', 'Hari Libur', 'Sinkron nasional ' . $tahun . ' | insert: ' . $sync['inserted'] . ', update: ' . $sync['updated'] . ', skip: ' . $sync['skipped']);

        echo json_encode([
            'success' => TRUE,
            'message' => 'Sinkron selesai. Ditambah ' . $sync['inserted'] . ', diperbarui ' . $sync['updated'] . ', dilewati ' . $sync['skipped'] . '.',
        ]);
    }

    public function edit($id)
    {
        $row = $this->HariLibur_model->get_by_id($id);
        if (!$row) { show_404(); return; }

        $this->_set_rules();
        if ($this->form_validation->run() === FALSE) {
            $this->render('master/harlibur/form', $this->_form_data($row));
            return;
        }

        $payload = $this->_payload();
        if ($this->HariLibur_model->tanggal_exists($payload['tanggal'], $id)) {
            $this->session->set_flashdata('error', 'Tanggal ' . tgl_indonesia($payload['tanggal']) . ' sudah terdaftar.');
            $this->render('master/harlibur/form', $this->_form_data($row));
            return;
        }

        $this->HariLibur_model->update($id, $payload);
        audit_log('EDIT', 'Hari Libur', $payload['nama_libur'] . ' (' . $payload['tanggal'] . ')');
        $this->session->set_flashdata('success', 'Hari libur berhasil diperbarui.');
        redirect('master/harlibur');
    }

    public function hapus($id)
    {
        $row = $this->HariLibur_model->get_by_id($id);
        if (!$row) { show_404(); return; }
        $this->HariLibur_model->delete($id);
        audit_log('HAPUS', 'Hari Libur', $row->nama_libur . ' (' . $row->tanggal . ')');
        $this->session->set_flashdata('success', 'Hari libur berhasil dihapus.');
        redirect('master/harlibur');
    }

    // -------------------------------------------------------
    private function _set_rules()
    {
        $this->form_validation->set_rules('tanggal',    'Tanggal',    'required|trim');
        $this->form_validation->set_rules('nama_libur', 'Nama Libur', 'required|trim|max_length[100]');
        $this->form_validation->set_rules('jenis',      'Jenis',      'required|in_list[NASIONAL,PERUSAHAAN]');
    }

    private function _payload()
    {
        return [
            'tanggal'    => $this->input->post('tanggal', TRUE),
            'nama_libur' => $this->input->post('nama_libur', TRUE),
            'jenis'      => $this->input->post('jenis', TRUE),
        ];
    }

    private function _form_data($row = NULL)
    {
        return [
            'page_title'    => $row ? 'Edit Hari Libur' : 'Tambah Hari Libur',
            'page_subtitle' => 'Kalender kerja perusahaan',
            'row'           => $row,
        ];
    }

    private function _fetch_national_holidays($tahun)
    {
        foreach (self::HOLIDAY_SYNC_SOURCES as $url) {
            $raw = $this->_http_get($url);
            if ($raw === NULL || $raw === '') {
                continue;
            }

            $json = json_decode($raw, TRUE);
            if (!is_array($json)) {
                continue;
            }

            $items = $this->_parse_holiday_source($json, $tahun);
            if (!empty($items)) {
                return $items;
            }
        }

        return [];
    }

    private function _parse_holiday_source(array $json, $tahun)
    {
        $items = [];
        foreach ($json as $tanggal => $detail) {
            if (strpos((string) $tanggal, (string) $tahun) !== 0) {
                continue;
            }

            $summary = '';
            $description = '';
            $isHoliday = TRUE;

            if (is_array($detail)) {
                $summaryValue = $detail['summary'] ?? $detail['holiday_name'] ?? $detail['name'] ?? $detail['nama'] ?? '';
                $descriptionValue = $detail['description'] ?? $detail['deskripsi'] ?? '';
                $summary = is_array($summaryValue) ? implode(', ', $summaryValue) : (string) $summaryValue;
                $description = is_array($descriptionValue) ? implode(', ', $descriptionValue) : (string) $descriptionValue;
                if (array_key_exists('holiday', $detail)) {
                    $isHoliday = (bool) $detail['holiday'];
                }
            } else {
                $summary = (string) $detail;
            }

            $combined = trim($summary . ' ' . $description);
            if (!$isHoliday || $combined === '') {
                continue;
            }
            if (stripos($combined, 'cuti bersama') !== FALSE) {
                continue;
            }

            $items[] = [
                'tanggal' => $tanggal,
                'nama_libur' => $summary !== '' ? $summary : 'Hari Libur Nasional',
                'jenis' => 'NASIONAL',
            ];
        }

        return $items;
    }

    private function _http_get($url)
    {
        if (function_exists('curl_init')) {
            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
            curl_setopt($ch, CURLOPT_TIMEOUT, 20);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
            curl_setopt($ch, CURLOPT_USERAGENT, 'PayrollJIG/1.0');
            $response = curl_exec($ch);
            $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            if ($httpCode >= 200 && $httpCode < 300) {
                return $response;
            }
        }

        if (ini_get('allow_url_fopen')) {
            $context = stream_context_create([
                'http' => [
                    'method' => 'GET',
                    'timeout' => 20,
                    'header' => "User-Agent: PayrollJIG/1.0\r\n",
                ],
            ]);
            $response = @file_get_contents($url, FALSE, $context);
            if ($response !== FALSE) {
                return $response;
            }
        }

        return NULL;
    }
}
