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

class Authority extends CI_Controller {

    public function __construct() {
        parent::__construct();
        ini_set('display_error', 1);
        $this->load->model('Authority_model');
        $this->load->library('form_validation');
    }

    /**
     * List authorities for a company
     */
    public function index($company_id = null) {
        error_reporting(1);
        ini_set('display_error', 1);
        
        // Check login
        $login_id = $this->session->userdata('id');
        if (empty($login_id)) {
            redirect('login');
        }
        
        $role_id = $this->session->userdata('role_id');
        
        // 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->session->userdata('company_id');
        }
        
        // Company is required for authority list
        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;
        }
        
        // Check company access
        require_company_access($company_id);
        
        $data['company_id'] = $company_id;
        
        // Get company name for display
        $company = $this->db->get_where('company', ['id' => $company_id])->row();
        $data['company_name'] = $company ? $company->company_name : '';
        
        // For User role (3), only show assigned authorities within this company
        if ($role_id == '3') {
            $allowed_authorities = get_allowed_authorities_by_company($company_id);
            if (!empty($allowed_authorities)) {
                $data['authorities'] = $this->Authority_model->get_by_ids_and_company($allowed_authorities, $company_id);
            } else {
                $data['authorities'] = [];
            }
        } else {
            // Super Admin and Admin see all authorities for this company
            $data['authorities'] = $this->Authority_model->get_all_by_company($company_id);
        }
        
        // Check which authorities have document heads (in use)
        $data['authority_has_doc_heads'] = [];
        foreach ($data['authorities'] as $auth) {
            $data['authority_has_doc_heads'][$auth->id] = $this->Authority_model->isInUse($auth->id);
        }
        
        $this->load->view('templates/header');
        $this->load->view('authority/index', $data);
        $this->load->view('layout/footer');
    }

    /**
     * Show create authority form
     */
    public function create($company_id = null)
    {
        // Check login
        $login_id = $this->session->userdata('id');
        if (empty($login_id)) {
            redirect('login');
        }
        
        // Get company_id
        if (!empty($company_id)) {
            $this->session->set_userdata('company_id', $company_id);
        } else {
            $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;
        }
        
        // Check company access and permissions
        require_company_access($company_id);
        require_edit_permission('authority/index/' . $company_id);
        
        // Get company details
        $company = $this->db->get_where('company', ['id' => $company_id])->row();
        $data['company_id'] = $company_id;
        $data['company_name'] = $company ? $company->company_name : '';

        // Validation rules
        $this->form_validation->set_rules(
            'authority_name',
            'Authority Name',
            'required|trim|callback_valid_authority_name',
            ['required' => 'The %s field is mandatory.']
        );
        $this->form_validation->set_rules('alias', 'Alias', 'trim');

        if ($this->form_validation->run() == FALSE) {
            $this->load->view('templates/header');
            $this->load->view('authority/create', $data);
            $this->load->view('layout/footer');
            return;
        }

        // ---------- AFTER VALIDATION ----------
        $authority_name = trim($this->input->post('authority_name'));
        $alias = trim($this->input->post('alias'));
        
        // Validate allowed characters
        $char_validation = validate_name_characters($authority_name);
        if (!$char_validation['valid']) {
            $data['error_message'] = $char_validation['message'];
            $this->load->view('templates/header');
            $this->load->view('authority/create', $data);
            $this->load->view('layout/footer');
            return;
        }

        // Normalize for duplicate check within company
        $normalized_name = $this->normalize_authority_name($authority_name);

        // Check duplicate within same company
        if ($this->Authority_model->isAuthorityExistsNormalizedInCompany($normalized_name, $company_id)) {
            $data['error_message'] = 'Authority name already exists in this company!';
            $this->load->view('templates/header');
            $this->load->view('authority/create', $data);
            $this->load->view('layout/footer');
            return;
        }
        
        // Check for duplicate alias name within same company
        if ($this->Authority_model->isAliasExistsInCompany($alias, $company_id)) {
            $data['error_message'] = 'Alias name already exists in this company!';
            $this->load->view('templates/header');
            $this->load->view('authority/create', $data);
            $this->load->view('layout/footer');
            return;
        }

        // Insert authority with company_id
        $this->Authority_model->insert([
            'authority_name' => $authority_name,
            'alias_name'     => $alias,
            'company_id'     => $company_id,
            'status'         => '1',
            'is_delete'      => 0,
            'created_date'   => date('Y-m-d')
        ]);

        $this->session->set_flashdata('message_type', 'success');
        $this->session->set_flashdata('message_name', 'Authority added successfully!');
        redirect('authority/index/' . $company_id);
    }

    /**
     * Edit authority
     */
    public function edit($id) {
        // Check login
        $login_id = $this->session->userdata('id');
        if (empty($login_id)) {
            redirect('login');
        }
        
        $company_id = $this->session->userdata('company_id');
        
        // Get authority and verify it belongs to this company
        $authority = $this->Authority_model->get($id);
        if (!$authority) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Authority not found.');
            redirect('authority/index/' . $company_id);
            return;
        }
        
        // Verify company ownership
        if ($authority->company_id != $company_id) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Access denied. This authority belongs to another company.');
            redirect('authority/index/' . $company_id);
            return;
        }
        
        // Permission check
        require_edit_permission('authority/index/' . $company_id);
        
        // Check if authority is in use
        if ($this->Authority_model->isInUse($id)) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Edit not allowed — Authority is in use by document heads.');
            redirect('authority/index/' . $company_id);
            return;
        }

        $data['authority'] = $authority;
        $data['company_id'] = $company_id;
        
        // Get company name
        $company = $this->db->get_where('company', ['id' => $company_id])->row();
        $data['company_name'] = $company ? $company->company_name : '';
        
        // Validation rules
        $this->form_validation->set_rules('authority_name', 'Authority Name', 'required|trim',
            array('required' => 'The %s field is mandatory.')
        );
        $this->form_validation->set_rules('alias_name', 'Alias', 'trim');

        if ($this->form_validation->run() == FALSE) {
            $this->load->view('templates/header');
            $this->load->view('authority/edit_authority', $data);
            $this->load->view('layout/footer');
        } else {
            $authority_name = trim($this->input->post('authority_name'));
            $alias_name = trim($this->input->post('alias_name'));
            
            // Validate allowed characters
            $char_validation = validate_name_characters($authority_name);
            if (!$char_validation['valid']) {
                $data['error_message'] = $char_validation['message'];
                $this->load->view('templates/header');
                $this->load->view('authority/edit_authority', $data);
                $this->load->view('layout/footer');
                return;
            }
            
            // Normalize for duplicate check
            $normalized_name = $this->normalize_authority_name($authority_name);

            // Check for duplicate within same company (excluding current record)
            if ($this->Authority_model->isAuthorityExistsNormalizedInCompany($normalized_name, $company_id, $id)) {
                $data['error_message'] = 'Authority name already exists in this company!';
                $this->load->view('templates/header');
                $this->load->view('authority/edit_authority', $data);
                $this->load->view('layout/footer');
                return;
            }
            
            // Check for duplicate alias name within same company (excluding current record)
            if ($this->Authority_model->isAliasExistsInCompany($alias_name, $company_id, $id)) {
                $data['error_message'] = 'Alias name already exists in this company!';
                $this->load->view('templates/header');
                $this->load->view('authority/edit_authority', $data);
                $this->load->view('layout/footer');
                return;
            }

            $this->Authority_model->update($id, [
                'authority_name' => $authority_name,
                'alias_name' => $alias_name
            ]);

            $this->session->set_flashdata('message_type', 'success');
            $this->session->set_flashdata('message_name', 'Authority updated successfully!');
            redirect('authority/index/' . $company_id);
        }
    }

    /**
     * Delete authority
     */
    public function delete($id) {
        // Check login
        $login_id = $this->session->userdata('id');
        if (empty($login_id)) {
            redirect('login');
        }
        
        $company_id = $this->session->userdata('company_id');
        
        // Get authority and verify it belongs to this company
        $authority = $this->Authority_model->get($id);
        if (!$authority || $authority->company_id != $company_id) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Authority not found or access denied.');
            redirect('authority/index/' . $company_id);
            return;
        }
        
        // Permission check
        require_delete_permission('authority/index/' . $company_id);
        
        // Check if authority is in use
        if ($this->Authority_model->isInUse($id)) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Delete not allowed — Authority is in use by document heads.');
            redirect('authority/index/' . $company_id);
            return;
        }

        $this->Authority_model->delete($id);

        if ($this->db->affected_rows() > 0) {
            $this->session->set_flashdata('message_type', 'success');
            $this->session->set_flashdata('message_name', 'Authority deleted successfully!');
        } else {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Authority not found or already deleted.');
        }

        redirect('authority/index/' . $company_id);
    }

    /**
     * Toggle authority status
     */
    public function toggle_status($id) {
        // Check login
        $login_id = $this->session->userdata('id');
        if (empty($login_id)) {
            redirect('login');
        }
        
        $company_id = $this->session->userdata('company_id');
        
        // Get authority and verify it belongs to this company
        $authority = $this->Authority_model->get($id);
        if (!$authority || $authority->company_id != $company_id) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Authority not found or access denied.');
            redirect('authority/index/' . $company_id);
            return;
        }
        
        // Permission check
        require_edit_permission('authority/index/' . $company_id);

        // Check if authority is in use
        if ($this->Authority_model->isInUse($id)) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Deactivation not allowed — Authority is in use by document heads.');
            redirect('authority/index/' . $company_id);
            return;
        }

        $new_status = ($authority->status == '0') ? '1' : '0';
        
        // If deactivating (status changing from 1 to 0), save deactivation details
        $deactivation_date = null;
        $deactivation_remarks = null;
        
        if ($new_status == '0' && $authority->status == '1') {
            $deactivation_date = $this->input->post('deactivation_date');
            $deactivation_remarks = $this->input->post('deactivation_remarks');
        }
        
        $this->Authority_model->update_status($id, $new_status, $deactivation_date, $deactivation_remarks);

        if ($this->db->affected_rows() > 0) {
            $this->session->set_flashdata('message_type', 'success');
            $this->session->set_flashdata('message_name', 'Authority status updated successfully!');
            
            // For AJAX requests, return JSON
            if ($this->input->is_ajax_request()) {
                echo json_encode(['success' => true, 'message' => 'Authority status updated successfully!']);
                return;
            }
        } else {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Failed to update authority status.');
            
            // For AJAX requests, return JSON
            if ($this->input->is_ajax_request()) {
                echo json_encode(['success' => false, 'message' => 'Failed to update authority status.']);
                return;
            }
        }

        redirect('authority/index/' . $company_id);
    }

    /**
     * View authority details
     */
    public function viewAuthority($id, $company_id = null)
    {
        // Check login
        $login_id = $this->session->userdata('id');
        if (empty($login_id)) {
            redirect('login');
        }

        if ($company_id) {
            $this->session->set_userdata('company_id', $company_id);
        } else {
            $company_id = $this->session->userdata('company_id');
        }

        $authority = $this->Authority_model->get($id);
        if (!$authority) {
            show_404();
        }
        
        // Verify company ownership
        if ($authority->company_id != $company_id) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Access denied. This authority belongs to another company.');
            redirect('authority/index/' . $company_id);
            return;
        }

        $data['view_mode'] = 'authority';
        $data['authority'] = $authority;
        $data['company_id'] = $company_id;

        $this->load->view('templates/header');
        $this->load->view('authority/view_authority', $data);
        $this->load->view('layout/footer');
    }

    /**
     * Validate authority name format
     */
    public function valid_authority_name($str)
    {
        // Allow ONLY alphabets, numbers, space, -, /, '
        if (!preg_match("/^[a-zA-Z0-9\s\-\/']+$/", $str)) {
            $this->form_validation->set_message(
                'valid_authority_name',
                "Authority Name can contain only letters, numbers, space, -, / and '"
            );
            return false;
        }
        return true;
    }

    /**
     * Normalize authority name for duplicate checking
     */
    private function normalize_authority_name($name)
    {
        return preg_replace("/[\s\-\/']+/", '', strtolower($name));
    }
}
