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

class Holiday extends CI_Controller {

    public function __construct()
    {
        parent::__construct();
        $this->load->database();
        $this->load->helper(['url', 'form']);
        $this->load->library('session');
        $this->load->model('Holiday_model');
        
        // Check authentication
        $login_id = $this->session->userdata('id');
        if (empty($login_id)) {
            if ($this->input->is_ajax_request()) {
                echo json_encode(['success' => false, 'message' => 'Session expired']);
                exit;
            }
            redirect('login');
        }
    }

    /**
     * Main holiday list page
     */
    public function index($company_id = null)
    {
        $this->session->set_userdata('menu', 'holiday');
        
        $year = $this->input->get('year') ?: date('Y');
        
        // Get company_id from URL parameter first, then fall back to session
        if (!empty($company_id)) {
            $this->session->set_userdata('company_id', $company_id);
        } else {
            $company_id = $this->input->get('company_id') ?: $this->session->userdata('company_id');
        }
        
        // Company is required
        if (empty($company_id)) {
            $this->session->set_flashdata('message_type', 'warning');
            $this->session->set_flashdata('message_name', 'Please select a company first.');
            redirect('company/companies');
            return;
        }
        
        require_company_access($company_id);
        
        // Get selected company details
        $selected_company = $this->db->get_where('company', ['id' => $company_id])->row();
        if (!$selected_company) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Company not found.');
            redirect('company/companies');
            return;
        }
        
        // Years from 2024 (system start) to current year + 1 (for advance planning)
        $startYear = 2024;
        $endYear = date('Y') + 1;
        $years = [];
        for ($y = $endYear; $y >= $startYear; $y--) {
            $years[] = $y;
        }
        
        // Get list of companies for the dropdown
        $role_id = $this->session->userdata('role_id');
        if ($role_id == '1') {
            // Super Admin - all companies
            $companies = $this->db->where('status', '1')->order_by('company_name')->get('company')->result();
        } else {
            // Admin/User - only assigned companies
            $allowed_company_ids = get_allowed_companies();
            if (!empty($allowed_company_ids)) {
                $companies = $this->db->where('status', '1')
                    ->where_in('id', $allowed_company_ids)
                    ->order_by('company_name')
                    ->get('company')->result();
            } else {
                $companies = [];
            }
        }
        
        $data = [
            'holidays' => $this->Holiday_model->getHolidaysByCompany($company_id, $year),
            'selected_year' => $year,
            'company_id' => $company_id,
            'selected_company_id' => $company_id,
            'selected_company' => $selected_company,
            'company_name' => $selected_company->company_name,
            'selected_country' => $selected_company->country,
            'companies' => $companies,
            'years' => $years
        ];
        
        $this->load->view('templates/header', $data);
        $this->load->view('holiday/index', $data);
        $this->load->view('templates/footer');
    }

    /**
     * Add a single holiday via AJAX
     */
    public function add()
    {
        // Permission check - edit permission required
        if (!can_edit()) {
            echo json_encode(['success' => false, 'message' => 'You do not have permission to add holidays.']);
            return;
        }
        
        $date = $this->input->post('date');
        $name = $this->input->post('name');
        $company_id = $this->input->post('company_id') ?: $this->session->userdata('company_id');
        
        if (empty($date) || empty($name)) {
            echo json_encode(['success' => false, 'message' => 'Date and name are required.']);
            return;
        }
        
        if (empty($company_id)) {
            echo json_encode(['success' => false, 'message' => 'Company is required.']);
            return;
        }
        
        // Check company access
        if (!has_company_access($company_id)) {
            echo json_encode(['success' => false, 'message' => 'Access denied to this company.']);
            return;
        }
        
        // Check for duplicate holiday on the same date for this company
        $existing = $this->db->where('holiday_date', $date)
            ->where('company_id', $company_id)
            ->where('is_deleted', 0)
            ->get('holidays')->row();
        if ($existing) {
            echo json_encode(['success' => false, 'message' => 'A holiday already exists on this date for this company.']);
            return;
        }
        
        $result = $this->Holiday_model->addHolidayForCompany($date, $name, $company_id);
        echo json_encode($result);
    }

    /**
     * Delete a holiday via AJAX
     */
    public function delete()
    {
        // Permission check - delete permission required
        if (!can_delete()) {
            echo json_encode(['success' => false, 'message' => 'You do not have permission to delete holidays.']);
            return;
        }
        
        $id = $this->input->post('id');
        $company_id = $this->session->userdata('company_id');
        
        if (empty($id)) {
            echo json_encode(['success' => false, 'message' => 'Invalid holiday ID.']);
            return;
        }
        
        // Verify holiday belongs to this company
        $holiday = $this->db->get_where('holidays', ['id' => $id])->row();
        if (!$holiday || $holiday->company_id != $company_id) {
            echo json_encode(['success' => false, 'message' => 'Holiday not found or access denied.']);
            return;
        }
        
        $result = $this->Holiday_model->deleteHoliday($id);
        echo json_encode($result);
    }

    /**
     * Import holidays from CSV file
     */
    public function import()
    {
        // Permission check - edit permission required
        if (!can_edit()) {
            echo json_encode(['success' => false, 'message' => 'You do not have permission to import holidays.']);
            return;
        }
        
        $year = $this->input->post('year') ?: date('Y');
        $company_id = $this->input->post('company_id') ?: $this->session->userdata('company_id');
        
        if (empty($company_id)) {
            echo json_encode(['success' => false, 'message' => 'Company is required.']);
            return;
        }
        
        // Check company access
        if (!has_company_access($company_id)) {
            echo json_encode(['success' => false, 'message' => 'Access denied to this company.']);
            return;
        }
        
        // Check if file was uploaded
        if (empty($_FILES['file']['name'])) {
            echo json_encode(['success' => false, 'message' => 'No file uploaded. Please select a file.']);
            return;
        }
        
        $config['upload_path'] = $this->config->item('documents_upload_path');
        $config['allowed_types'] = 'csv|xlsx|xls';
        $config['max_size']      = 2048;
        $config['file_name']     = 'holidays_' . time();
        $config['overwrite']     = TRUE;
        
        // Create directory if it doesn't exist
        if (!is_dir($config['upload_path'])) {
            mkdir($config['upload_path'], 0777, true);
        }
        
        $this->load->library('upload');
        $this->upload->initialize($config);
        
        if (!$this->upload->do_upload('file')) {
            echo json_encode(['success' => false, 'message' => $this->upload->display_errors('', '')]);
            return;
        }
        
        $uploadData = $this->upload->data();
        $filePath = $uploadData['full_path'];
        $ext = strtolower($uploadData['file_ext']);
        
        $holidays = [];
        
        if ($ext == '.csv') {
            // Parse CSV
            if (($handle = fopen($filePath, "r")) !== FALSE) {
                $header = fgetcsv($handle); // Skip header row
                
                while (($row = fgetcsv($handle)) !== FALSE) {
                    if (count($row) >= 2) {
                        $dateVal = trim($row[0]);
                        $nameVal = trim($row[1]);
                        
                        $parsedDate = $this->_parseDate($dateVal);
                        if ($parsedDate !== false) {
                            $holidays[] = [
                                'date' => $parsedDate,
                                'name' => $nameVal
                            ];
                        }
                    }
                }
                fclose($handle);
            }
        } else {
            // For Excel files, use PhpSpreadsheet
            try {
                require_once FCPATH . 'vendor/autoload.php';
                
                $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($filePath);
                $sheet = $spreadsheet->getActiveSheet();
                $rows = $sheet->toArray();
                
                for ($i = 1; $i < count($rows); $i++) {
                    $row = $rows[$i];
                    if (count($row) >= 2 && !empty($row[0])) {
                        $dateVal = trim($row[0]);
                        $nameVal = trim($row[1]);
                        
                        if (is_numeric($dateVal)) {
                            $timestamp = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToTimestamp($dateVal);
                            $parsedDate = date('Y-m-d', $timestamp);
                        } else {
                            $parsedDate = $this->_parseDate($dateVal);
                        }
                        
                        if ($parsedDate !== false) {
                            $holidays[] = [
                                'date' => $parsedDate,
                                'name' => $nameVal
                            ];
                        }
                    }
                }
            } catch (Exception $e) {
                @unlink($filePath);
                echo json_encode(['success' => false, 'message' => 'Error reading Excel file: ' . $e->getMessage()]);
                return;
            }
        }
        
        @unlink($filePath);
        
        if (empty($holidays)) {
            echo json_encode(['success' => false, 'message' => 'No valid holidays found in file.']);
            return;
        }
        
        $result = $this->Holiday_model->importHolidaysForCompany($holidays, $year, $company_id);
        echo json_encode([
            'success' => true,
            'message' => "Import complete. Added: {$result['added']}, Skipped (duplicates): {$result['skipped']}"
        ]);
    }

    /**
     * Clear all holidays for a year
     */
    public function clearYear()
    {
        // Permission check - delete permission required
        if (!can_delete()) {
            echo json_encode(['success' => false, 'message' => 'You do not have permission to clear holidays.']);
            return;
        }
        
        $year = $this->input->post('year');
        $company_id = $this->input->post('company_id') ?: $this->session->userdata('company_id');
        
        if (empty($year)) {
            echo json_encode(['success' => false, 'message' => 'Year is required.']);
            return;
        }
        
        if (empty($company_id)) {
            echo json_encode(['success' => false, 'message' => 'Company is required.']);
            return;
        }
        
        // Check company access
        if (!has_company_access($company_id)) {
            echo json_encode(['success' => false, 'message' => 'Access denied to this company.']);
            return;
        }
        
        $result = $this->Holiday_model->clearHolidaysForCompany($year, $company_id);
        echo json_encode(['success' => true, 'message' => "All holidays for $year have been cleared."]);
    }

    /**
     * Get holidays for a year via AJAX
     */
    public function getHolidays()
    {
        $year = $this->input->post('year') ?: date('Y');
        $company_id = $this->input->post('company_id') ?: $this->session->userdata('company_id');
        
        $holidays = $this->Holiday_model->getHolidaysByCompany($company_id, $year);
        echo json_encode(['success' => true, 'holidays' => $holidays]);
    }

    /**
     * API: Get adjusted due date
     */
    public function getAdjustedDueDate()
    {
        $dueDay = (int)$this->input->post('due_day');
        $month = (int)$this->input->post('month');
        $year = (int)$this->input->post('year');
        $company_id = $this->input->post('company_id') ?: $this->session->userdata('company_id');
        
        if (!$dueDay || !$month || !$year) {
            echo json_encode(['success' => false, 'message' => 'Invalid parameters']);
            return;
        }
        
        $result = $this->Holiday_model->getAdjustedDueDateForCompany($dueDay, $month, $year, $company_id);
        echo json_encode(['success' => true, 'data' => $result]);
    }

    /**
     * Download sample CSV template
     */
    public function downloadTemplate()
    {
        $data = "Date,Holiday Name\n";
        $data .= "01-01-2025,New Year's Day\n";
        $data .= "26-01-2025,Republic Day\n";
        $data .= "15-08-2025,Independence Day\n";
        $data .= "02-10-2025,Gandhi Jayanti\n";
        $data .= "25-12-2025,Christmas\n";
        
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="holiday_template.csv"');
        echo $data;
        exit;
    }

    /**
     * Parse date string to Y-m-d format
     */
    private function _parseDate($dateStr)
    {
        if (empty($dateStr)) {
            return false;
        }
        
        $dateStr = trim($dateStr);
        
        // Try DD-MM-YYYY format first
        $date = DateTime::createFromFormat('d-m-Y', $dateStr);
        if ($date !== false) {
            return $date->format('Y-m-d');
        }
        
        // Try DD/MM/YYYY format
        $date = DateTime::createFromFormat('d/m/Y', $dateStr);
        if ($date !== false) {
            return $date->format('Y-m-d');
        }
        
        // Try YYYY-MM-DD format (ISO)
        $date = DateTime::createFromFormat('Y-m-d', $dateStr);
        if ($date !== false) {
            return $date->format('Y-m-d');
        }
        
        // Try YYYY/MM/DD format
        $date = DateTime::createFromFormat('Y/m/d', $dateStr);
        if ($date !== false) {
            return $date->format('Y-m-d');
        }
        
        // Try MM-DD-YYYY format (US)
        $date = DateTime::createFromFormat('m-d-Y', $dateStr);
        if ($date !== false) {
            return $date->format('Y-m-d');
        }
        
        // Try MM/DD/YYYY format (US)
        $date = DateTime::createFromFormat('m/d/Y', $dateStr);
        if ($date !== false) {
            return $date->format('Y-m-d');
        }
        
        // Fallback to strtotime
        $timestamp = strtotime($dateStr);
        if ($timestamp !== false) {
            return date('Y-m-d', $timestamp);
        }
        
        return false;
    }
}
