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

class Document extends CI_Controller {

    public function index()
    {
        redirect('document/allDocuments');
    }
    
    /**
     * List all documents for a company
     */
    public function allDocuments($company_id = null)
    {   
        $this->session->set_userdata('menu', 'document');
        $login_id = $this->session->userdata('id');
        if ($login_id == '') {
            redirect('login');
        }
        
        // Get company_id from URL parameter first, then fall back to session
        if (!empty($company_id)) {
            require_company_access($company_id);
            $this->session->set_userdata('company_id', $company_id);
        } else {
            $company_id = $this->session->userdata('company_id');
        }
        
        // Company is required for document 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;
        }
        
        // Verify company access
        require_company_access($company_id);
        
        $role_id = $this->session->userdata('role_id');
        
        // Get documents for this company
        if ($role_id == '3') {
            // User role - only show documents from their assigned document heads within this company
            $allowed_doc_heads = get_allowed_document_types_by_company($company_id);
            if (!empty($allowed_doc_heads)) {
                $placeholders = implode(',', array_fill(0, count($allowed_doc_heads), '?'));
                $sql = "SELECT DISTINCT d.* FROM documents d
                        INNER JOIN mandatory_documents md ON md.document_id = d.id
                        WHERE d.company_id = ? 
                        AND md.type_id IN ({$placeholders})
                        AND d.status = '1'
                        ORDER BY d.document_name ASC";
                $params = array_merge([$company_id], $allowed_doc_heads);
                $query = $this->db->query($sql, $params);
                $documents = $query->result_array();
            } else {
                $documents = [];
            }
        } else {
            // Super Admin and Admin see all documents for this company
            $documents = $this->db->where('company_id', $company_id)
                ->where('status', '1')
                ->order_by('document_name', 'ASC')
                ->get('documents')
                ->result_array();
        }
        
        // Check which documents have uploads for this company
        $document_has_uploads = [];
        $uploads_query = $this->db->query("
            SELECT document_id, COUNT(*) as upload_count
            FROM uploaded_documents
            WHERE company_id = ? AND is_deleted = 0
            GROUP BY document_id
        ", array($company_id));
        foreach ($uploads_query->result() as $row) {
            $document_has_uploads[$row->document_id] = $row->upload_count;
        }
        
        // Check which documents are in use (in mandatory_documents)
        $document_in_use = [];
        $in_use_query = $this->db->query("
            SELECT DISTINCT document_id FROM mandatory_documents WHERE company_id = ?
        ", array($company_id));
        foreach ($in_use_query->result() as $row) {
            $document_in_use[$row->document_id] = true;
        }
        
        // Get company name for display
        $company = $this->db->get_where('company', ['id' => $company_id])->row();
        $company_name = $company ? $company->company_name : '';
        
        $this->load->view('templates/header');
        $this->load->view('document/all_document', array(
            'authority_list' => $documents,
            'company_id' => $company_id,
            'company_name' => $company_name,
            'document_has_uploads' => $document_has_uploads,
            'document_in_use' => $document_in_use
        ));
    }
    
    /**
     * Show add document form
     */
    public function addDocument($company_id = null)
    {
        $this->session->set_userdata('menu', 'document');
        $login_id = $this->session->userdata('id');
        if ($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('document/allDocuments/' . $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 : '';
        
        $this->load->view('templates/header');
        $this->load->view('document/add_document', $data);
    }
    
    /**
     * Save new document
     */
    public function saveDocument()
    {
        $this->session->set_userdata('menu', 'document');
        $login_id = $this->session->userdata('id');
        
        if ($login_id == '') {
            redirect('login');
        }
        
        $company_id = $this->session->userdata('company_id');
        
        // Company is required
        if (empty($company_id)) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Company context required.');
            redirect('document/allDocuments');
            return;
        }
        
        // Permission check
        require_company_access($company_id);
        require_edit_permission('document/allDocuments/' . $company_id);
        
        $document_name = trim($_POST['document_name']);
        
        // Validate allowed characters
        $char_validation = validate_name_characters($document_name);
        if (!$char_validation['valid']) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', $char_validation['message']);
            redirect('document/addDocument/' . $company_id);
            return;
        }
        
        // Check for duplicate document name within this company (normalized - ignoring spaces and special chars)
        $duplicate = check_duplicate_name(
            'documents',
            'document_name',
            $document_name,
            null,
            ['company_id' => $company_id, 'status' => '1']
        );
            
        if ($duplicate) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'A similar document name already exists in this company!');
            redirect('document/addDocument/' . $company_id);
            return;
        }
        
        // Insert document with company_id
        $this->db->insert('documents', [
            'document_name' => $document_name,
            'company_id' => $company_id,
            'status' => '1'
        ]);
        
        $this->session->set_flashdata('message_type', 'success');
        $this->session->set_flashdata('message_name', 'New Document Created Successfully');
        
        redirect('document/allDocuments/' . $company_id);
    }
    
    /**
     * Delete document
     */
    public function deleteDocument($id)
    {
        $this->session->set_userdata('menu', 'document');
        $login_id = $this->session->userdata('id');
        
        if ($login_id == '') {
            redirect('login');
        }
        
        $company_id = $this->session->userdata('company_id');
        
        // Get document and verify it belongs to this company
        $document = $this->db->get_where('documents', ['id' => $id])->row();
        if (!$document || $document->company_id != $company_id) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Document not found or access denied.');
            redirect('document/allDocuments/' . $company_id);
            return;
        }
        
        // Permission check
        require_delete_permission('document/allDocuments/' . $company_id);

        // Check if document has uploads
        if ($this->id_exists('uploaded_documents', $id, $company_id)) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Delete is not allowed — Document has uploads.');
            redirect('document/allDocuments/' . $company_id);
            return;
        }
        
        // Check if document is in use in mandatory_documents
        $in_use = $this->db->where('document_id', $id)
            ->where('company_id', $company_id)
            ->count_all_results('mandatory_documents') > 0;
        if ($in_use) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Delete is not allowed — Document is linked to document heads.');
            redirect('document/allDocuments/' . $company_id);
            return;
        }
        
        // Soft delete - set status to '0' instead of deleting
        $this->db->where('id', $id)->update('documents', ['status' => '0']);
        
        $this->session->set_flashdata('message_type', 'success');
        $this->session->set_flashdata('message_name', 'Document Deleted Successfully');
        redirect('document/allDocuments/' . $company_id);
    }
    
    /**
     * Edit document
     */
    public function editDocument($id)
    {
        $login_id = $this->session->userdata('id');
        
        if ($login_id == '') {
            redirect('login');
        }
        
        $this->session->set_userdata('menu', 'document');
        $company_id = $this->session->userdata('company_id');
        
        // Get document and verify it belongs to this company
        $document = $this->db->get_where('documents', ['id' => $id])->row();
        if (!$document) {
            redirect('document/allDocuments/' . $company_id);
            return;
        }
        
        // Verify company ownership
        if ($document->company_id != $company_id) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Access denied. This document belongs to another company.');
            redirect('document/allDocuments/' . $company_id);
            return;
        }

        // Check if document has uploads
        $has_uploads = $this->db->where('document_id', $id)
            ->where('company_id', $company_id)
            ->where('is_deleted', 0)
            ->count_all_results('uploaded_documents');
        
        // View-only if user doesn't have edit permission OR document has uploads
        $is_view_only = !can_edit() || ($has_uploads > 0);
        
        // Get company name
        $company = $this->db->get_where('company', ['id' => $company_id])->row();
        
        $this->load->view('templates/header');
        $this->load->view('document/edit_document', array(
            'authority_data' => [(array)$document],
            'has_uploads' => $has_uploads,
            'is_view_only' => $is_view_only,
            'company_id' => $company_id,
            'company_name' => $company ? $company->company_name : ''
        ));
    }
    
    /**
     * Update document
     */
    public function updateDocument()
    {
        $login_id = $this->session->userdata('id');
        
        if ($login_id == '') {
            redirect('login');
        }
        
        $this->session->set_userdata('menu', 'document');
        $company_id = $this->session->userdata('company_id');
        $id = $_POST['id'];
        
        // Get document and verify it belongs to this company
        $document = $this->db->get_where('documents', ['id' => $id])->row();
        if (!$document || $document->company_id != $company_id) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Access denied.');
            redirect('document/allDocuments/' . $company_id);
            return;
        }
        
        // Permission check
        require_edit_permission('document/allDocuments/' . $company_id);
        
        $document_name = trim($_POST['document_name']);
        
        // Validate allowed characters
        $char_validation = validate_name_characters($document_name);
        if (!$char_validation['valid']) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', $char_validation['message']);
            redirect('document/editDocument/' . $id);
            return;
        }
        
        // Check for duplicate document name within this company (normalized - ignoring spaces and special chars)
        $duplicate = check_duplicate_name(
            'documents',
            'document_name',
            $document_name,
            $id,
            ['company_id' => $company_id, 'status' => '1']
        );
            
        if ($duplicate) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'A similar document name already exists in this company!');
            redirect('document/editDocument/' . $id);
            return;
        }
        
        $this->db->where('id', $id)->update('documents', [
            'document_name' => $document_name
        ]);
        
        $this->session->set_flashdata('message_type', 'success');
        $this->session->set_flashdata('message_name', 'Document Successfully Updated');

        redirect('document/allDocuments/' . $company_id);
    }
    
    /**
     * Change document status (AJAX)
     */
    public function changeStatus()
    {
        if (!can_edit()) {
            echo json_encode([
                'success' => false,
                'message' => 'You do not have permission to change status.'
            ]);
            return;
        }
        
        $id = $this->input->post('id');
        $status = $this->input->post('status');
        $company_id = $this->session->userdata('company_id');
        
        // Verify document belongs to this company
        $document = $this->db->get_where('documents', ['id' => $id])->row();
        if (!$document || $document->company_id != $company_id) {
            echo json_encode([
                'success' => false,
                'message' => 'Access denied.'
            ]);
            return;
        }

        if ($this->id_exists('uploaded_documents', $id, $company_id)) {
            echo json_encode([
                'success' => false,
                'message' => 'Deactivation not allowed — Document in use.'
            ]);
            return;
        }

        $this->db->where('id', $id)->update('documents', ['status' => $status]);

        if ($this->db->affected_rows() > 0) {
            echo json_encode([
                'success' => true,
                'message' => 'Status updated successfully.',
                'new_status' => $status
            ]);
        } else {
            echo json_encode([
                'success' => false,
                'message' => 'Failed to update status.'
            ]);
        }
    }
    
    // ==================== DOCUMENT GROUPS ====================
    
    /**
     * List document groups for a company
     */
    public function groupList($company_id = null)
    {
        $login_id = $this->session->userdata('id');
        
        if ($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;
        }
        
        require_company_access($company_id);
        
        $role_id = $this->session->userdata('role_id');
        
        // Get document groups for this company
        $sql = "SELECT 
                    g.id,
                    g.document_id,
                    g.grouped_doc_id,
                    d.document_name AS main_doc_name,
                    string_agg(d2.document_name, ', ') AS grouped_doc_names
                FROM document_groups g
                LEFT JOIN documents d 
                    ON d.id = g.document_id::int
                LEFT JOIN LATERAL (
                    SELECT document_name
                    FROM documents
                    WHERE id IN (
                        SELECT unnest(string_to_array(g.grouped_doc_id, ',')::int[])
                    )
                ) AS d2 ON TRUE
                WHERE g.company_id = ?
                GROUP BY g.id, g.document_id, g.grouped_doc_id, d.document_name
                ORDER BY g.id ASC";
        $document_query = $this->db->query($sql, [$company_id]);
        $document_data = $document_query->result_array();
        
        // Check which groups have uploaded documents
        $group_status = [];
        $uploaded_docs_query = $this->db->query("
            SELECT DISTINCT document_id
            FROM uploaded_documents
            WHERE company_id = ? AND is_deleted = 0
        ", array($company_id));
        
        $uploaded_doc_ids = [];
        foreach ($uploaded_docs_query->result() as $row) {
            $uploaded_doc_ids[$row->document_id] = true;
        }
        
        foreach ($document_data as $group) {
            $main_doc_id = $group['document_id'];
            $child_doc_ids = !empty($group['grouped_doc_id']) ? explode(',', $group['grouped_doc_id']) : [];
            $all_doc_ids = array_merge([$main_doc_id], $child_doc_ids);
            
            $all_uploaded = true;
            foreach ($all_doc_ids as $doc_id) {
                if (!isset($uploaded_doc_ids[trim($doc_id)])) {
                    $all_uploaded = false;
                    break;
                }
            }
            
            $group_status[$group['id']] = [
                'all_uploaded' => $all_uploaded
            ];
        }
        
        // Get company name
        $company = $this->db->get_where('company', ['id' => $company_id])->row();
        
        $this->load->view('templates/header');
        $this->load->view('document/group_list', array(
            'document_data' => $document_data,
            'group_status' => $group_status,
            'company_id' => $company_id,
            'company_name' => $company ? $company->company_name : ''
        ));
    }
    
    /**
     * Show add document group form
     */
    public function addDocumentGroup($company_id = null)
    {
        $login_id = $this->session->userdata('id');
        
        if ($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;
        }
        
        require_company_access($company_id);
        require_edit_permission('document/groupList/' . $company_id);
        
        // Get documents for this company
        $document_data = $this->db->where('company_id', $company_id)
            ->where('status', '1')
            ->order_by('document_name', 'ASC')
            ->get('documents')
            ->result_array();

        if (empty($document_data)) {
            $this->session->set_flashdata('message_type', 'warning');
            $this->session->set_flashdata('message_name', 'Please create documents first.');
            redirect('document/groupList/' . $company_id);
            return;
        }
        
        // Get existing groups for this company
        $all_groups = $this->db->where('company_id', $company_id)
            ->get('document_groups')
            ->result_array();
        
        // Get company name
        $company = $this->db->get_where('company', ['id' => $company_id])->row();
        
        $this->load->view('templates/header');
        $this->load->view('document/add_group', array(
            'document_data' => $document_data,
            'all_groups' => $all_groups,
            'company_id' => $company_id,
            'company_name' => $company ? $company->company_name : ''
        ));
    }
    
    /**
     * Save document group
     */
    public function saveGroup()
    {
        $login_id = $this->session->userdata('id');
        
        if ($login_id == '') {
            redirect('login');
        }
        
        $company_id = $this->session->userdata('company_id');
        
        if (empty($company_id)) {
            redirect('document/groupList');
            return;
        }
        
        require_company_access($company_id);
        require_edit_permission('document/groupList/' . $company_id);
        
        $main_id = $_POST['main_document'];
        $child = implode(',', $_POST['child_document']);
        
        // Insert with company_id
        $this->db->insert('document_groups', [
            'document_id' => $main_id,
            'grouped_doc_id' => $child,
            'company_id' => $company_id
        ]);
        
        $this->session->set_flashdata('message_type', 'success');
        $this->session->set_flashdata('message_name', 'Document Group Created Successfully');
        redirect('document/groupList/' . $company_id);
    }
    
    /**
     * Edit document group
     */
    public function groupEdit($id)
    {
        $login_id = $this->session->userdata('id');
        
        if ($login_id == '') {
            redirect('login');
        }
        
        $company_id = $this->session->userdata('company_id');
        
        // Get group and verify it belongs to this company
        $group_data = $this->db->get_where('document_groups', ['id' => $id])->result_array();
        
        if (empty($group_data) || $group_data[0]['company_id'] != $company_id) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Document group not found or access denied.');
            redirect('document/groupList/' . $company_id);
            return;
        }
        
        // Get documents for this company
        $document_data = $this->db->where('company_id', $company_id)
            ->where('status', '1')
            ->order_by('document_name', 'ASC')
            ->get('documents')
            ->result_array();
        
        // Get all groups for this company
        $all_groups = $this->db->where('company_id', $company_id)
            ->get('document_groups')
            ->result_array();
        
        // Check if all documents in group are uploaded (view-only mode)
        $is_view_only = false;
        $main_doc_id = $group_data[0]['document_id'];
        $child_doc_ids = !empty($group_data[0]['grouped_doc_id']) ? explode(',', $group_data[0]['grouped_doc_id']) : [];
        $all_doc_ids = array_merge([$main_doc_id], $child_doc_ids);
        
        $uploaded_docs_query = $this->db->query("
            SELECT DISTINCT document_id
            FROM uploaded_documents
            WHERE company_id = ? AND is_deleted = 0
        ", array($company_id));
        
        $uploaded_doc_ids = [];
        foreach ($uploaded_docs_query->result() as $row) {
            $uploaded_doc_ids[$row->document_id] = true;
        }
        
        $all_uploaded = true;
        foreach ($all_doc_ids as $doc_id) {
            if (!isset($uploaded_doc_ids[trim($doc_id)])) {
                $all_uploaded = false;
                break;
            }
        }
        $is_view_only = $all_uploaded || !can_edit();
        
        // Get company name
        $company = $this->db->get_where('company', ['id' => $company_id])->row();
        
        $this->load->view('templates/header');
        $this->load->view('document/edit_group', array(
            'document_data' => $document_data,
            'group_data' => $group_data,
            'is_view_only' => $is_view_only,
            'all_groups' => $all_groups,
            'current_group_id' => $id,
            'company_id' => $company_id,
            'company_name' => $company ? $company->company_name : ''
        ));
    }
    
    /**
     * Update document group
     */
    public function updateGroup()
    {
        $login_id = $this->session->userdata('id');
        
        if ($login_id == '') {
            redirect('login');
        }
        
        $company_id = $this->session->userdata('company_id');
        $id = $_POST['id'];
        
        // Verify group belongs to this company
        $group = $this->db->get_where('document_groups', ['id' => $id])->row();
        if (!$group || $group->company_id != $company_id) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Access denied.');
            redirect('document/groupList/' . $company_id);
            return;
        }
        
        require_edit_permission('document/groupList/' . $company_id);
        
        $main_id = $_POST['main_document'];
        $child = implode(',', $_POST['child_document']);
        
        $this->db->where('id', $id)->update('document_groups', [
            'document_id' => $main_id,
            'grouped_doc_id' => $child
        ]);
        
        $this->session->set_flashdata('message_type', 'success');
        $this->session->set_flashdata('message_name', 'Document Group Updated Successfully');
        redirect('document/groupList/' . $company_id);
    }
    
    /**
     * Delete document group
     */
    public function groupDelete($id)
    {
        $login_id = $this->session->userdata('id');
        
        if ($login_id == '') {
            redirect('login');
        }
        
        $company_id = $this->session->userdata('company_id');
        
        // Verify group belongs to this company
        $group = $this->db->get_where('document_groups', ['id' => $id])->row();
        if (!$group || $group->company_id != $company_id) {
            $this->session->set_flashdata('message_type', 'error');
            $this->session->set_flashdata('message_name', 'Access denied.');
            redirect('document/groupList/' . $company_id);
            return;
        }
        
        require_delete_permission('document/groupList/' . $company_id);
        
        // Soft delete - set status to '0' instead of deleting
        $this->db->where('id', $id)->update('document_groups', ['status' => '0']);
        
        $this->session->set_flashdata('message_type', 'success');
        $this->session->set_flashdata('message_name', 'Document Group Deleted Successfully');
        redirect('document/groupList/' . $company_id);
    }
    
    /**
     * Check if a document has records in a table
     */
    private function id_exists($table, $document_id, $company_id = null)
    {
        $this->db->where('document_id', $document_id);
        if ($company_id) {
            $this->db->where('company_id', $company_id);
        }
        $this->db->where('is_deleted', 0);
        return $this->db->count_all_results($table) > 0;
    }
}
