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

/**
 * Admin Controller
 * 
 * @property CI_DB_query_builder $db
 * @property CI_Input $input
 * @property CI_Form_validation $form_validation
 * @property CI_Upload $upload
 * @property CI_Session $session
 * @property User_model $User_model
 * @property Campaign_model $Campaign_model
 * @property Data_model $Data_model
 * @property Send_model $Send_model
 * @property Log_model $Log_model
 * @property Message_schedule_model $Message_schedule_model
 */
class Admin extends CI_Controller {

    public function __construct() {
        parent::__construct();
        
        // Check if user is logged in
        if (!is_logged_in()) {
            redirect('login');
        }
        
        // Check if user is admin
        if (!is_admin()) {
            set_flash('error', 'Access denied. Admin privileges required.');
            redirect('user/dashboard');
        }
        
        // Load models
        $this->load->model('User_model');
        $this->load->model('Campaign_model');
        $this->load->model('Data_model');
        $this->load->model('Send_model');
        $this->load->model('Log_model');
        $this->load->model('Message_schedule_model');
        $this->load->library('upload');
    }

    /**
     * Admin Dashboard
     */
    public function dashboard() {
        $data['page_title'] = 'Admin Dashboard';
        
        // Get statistics
        $data['campaign_stats'] = $this->Campaign_model->get_dashboard_stats();
        $data['user_count'] = $this->User_model->count_users('user');
        $data['data_stats'] = $this->Data_model->get_dashboard_stats();
        $data['login_stats'] = $this->Log_model->get_login_stats();
        
        // Get recent activity
        $data['recent_logins'] = $this->Log_model->get_recent_logins(5);
        $data['chart_data'] = $this->Campaign_model->get_performance_chart_data(7);
        
        $this->load->view('admin/header', $data);
        $this->load->view('admin/dashboard', $data);
        $this->load->view('admin/footer');
    }

    /**
     * User Management - List
     */
    public function users() {
        try {
            $data['page_title'] = 'User Management';
            
            // Pagination
            $per_page = 10;
            $page = $this->input->get('page') ? (int)$this->input->get('page') : 1;
            $offset = ($page - 1) * $per_page;
            
            $data['users'] = $this->User_model->get_all_users($per_page, $offset, 'user');
            $data['total_users'] = $this->User_model->count_users('user');
            $data['pagination'] = $this->_create_pagination($data['total_users'], $per_page, 'admin/users');
            
            $this->load->view('admin/header', $data);
            $this->load->view('admin/users/list', $data);
            $this->load->view('admin/footer');
        } catch (Exception $e) {
            log_message('error', 'Admin users error: ' . $e->getMessage());
            log_message('error', 'Stack trace: ' . $e->getTraceAsString());
            show_error('An error occurred while loading users. Please contact the administrator.', 500);
        }
    }

    /**
     * User Management - Create
     */
    public function user_create() {
        $data['page_title'] = 'Create User';
        
        if ($this->input->method() == 'post') {
            $this->form_validation->set_rules('username', 'Username', 'required|trim|is_unique[users.username]');
            $this->form_validation->set_rules('email', 'Email', 'required|valid_email|is_unique[users.email]');
            $this->form_validation->set_rules('password', 'Password', 'required|min_length[6]');
            $this->form_validation->set_rules('status', 'Status', 'required|in_list[active,inactive]');
            
            if ($this->form_validation->run() === TRUE) {
                $user_data = [
                    'username' => $this->input->post('username'),
                    'email' => $this->input->post('email'),
                    'password' => $this->input->post('password'),
                    'role' => 'user',
                    'status' => $this->input->post('status')
                ];
                
                if ($this->User_model->create_user($user_data)) {
                    $this->Log_model->log_audit(current_user_id(), 'Create User', 'User Management', 'Created user: ' . $user_data['username']);
                    set_flash('success', 'User created successfully.');
                    redirect('admin/users');
                } else {
                    set_flash('error', 'Failed to create user.');
                }
            }
        }
        
        $this->load->view('admin/header', $data);
        $this->load->view('admin/users/create', $data);
        $this->load->view('admin/footer');
    }

    /**
     * User Management - Edit
     */
    public function user_edit($id) {
        $data['page_title'] = 'Edit User';
        $data['user'] = $this->User_model->get_by_id($id);
        
        if (!$data['user']) {
            set_flash('error', 'User not found.');
            redirect('admin/users');
        }
        
        if ($this->input->method() == 'post') {
            $this->form_validation->set_rules('username', 'Username', 'required|trim');
            $this->form_validation->set_rules('email', 'Email', 'required|valid_email');
            $this->form_validation->set_rules('status', 'Status', 'required|in_list[active,inactive]');
            
            if ($this->form_validation->run() === TRUE) {
                $update_data = [
                    'username' => $this->input->post('username'),
                    'email' => $this->input->post('email'),
                    'status' => $this->input->post('status')
                ];
                
                if ($this->input->post('password')) {
                    $update_data['password'] = $this->input->post('password');
                }
                
                if ($this->User_model->update_user($id, $update_data)) {
                    $this->Log_model->log_audit(current_user_id(), 'Update User', 'User Management', 'Updated user ID: ' . $id);
                    set_flash('success', 'User updated successfully.');
                    redirect('admin/users');
                } else {
                    set_flash('error', 'Failed to update user.');
                }
            }
        }
        
        $this->load->view('admin/header', $data);
        $this->load->view('admin/users/edit', $data);
        $this->load->view('admin/footer');
    }

    /**
     * User Management - Delete
     */
    public function user_delete($id) {
        $user = $this->User_model->get_by_id($id);
        
        if (!$user) {
            set_flash('error', 'User not found.');
        } elseif ($this->User_model->delete_user($id)) {
            $this->Log_model->log_audit(current_user_id(), 'Delete User', 'User Management', 'Deleted user ID: ' . $id);
            set_flash('success', 'User deleted successfully.');
        } else {
            set_flash('error', 'Failed to delete user.');
        }
        
        redirect('admin/users');
    }

    /**
     * User Management - Toggle Status
     */
    public function user_toggle_status($id) {
        if ($this->User_model->toggle_status($id)) {
            $this->Log_model->log_audit(current_user_id(), 'Toggle User Status', 'User Management', 'Toggled status for user ID: ' . $id);
            set_flash('success', 'User status updated.');
        } else {
            set_flash('error', 'Failed to update user status.');
        }
        
        redirect('admin/users');
    }

    /**
     * Campaign Management - List
     */
    public function campaigns() {
        $data['page_title'] = 'Campaign Management';
        
        // Pagination
        $per_page = 10;
        $page = $this->input->get('page') ? $this->input->get('page') : 1;
        $offset = ($page - 1) * $per_page;
        
        $data['campaigns'] = $this->Campaign_model->get_all_campaigns($per_page, $offset);
        $data['total_campaigns'] = $this->Campaign_model->count_campaigns();
        $data['pagination'] = $this->_create_pagination($data['total_campaigns'], $per_page, 'admin/campaigns');
        
        $this->load->view('admin/header', $data);
        $this->load->view('admin/campaigns/list', $data);
        $this->load->view('admin/footer');
    }

    /**
     * Campaign Management - Create
     */
    public function campaign_create() {
        $data['page_title'] = 'Create Campaign';
        
        if ($this->input->method() == 'post') {
            $this->form_validation->set_rules('name', 'Campaign Name', 'required|trim');
            $this->form_validation->set_rules('type', 'Campaign Type', 'required|in_list[SMS,WhatsApp,WhatsApp Image,Status Messaging,Custom]');
            $this->form_validation->set_rules('fail_percentage', 'Fail Percentage', 'required|numeric|greater_than_equal_to[0.01]|less_than_equal_to[100]');
            
            if ($this->form_validation->run() === TRUE) {
                $campaign_data = [
                    'name' => $this->input->post('name'),
                    'type' => $this->input->post('type'),
                    'fail_percentage' => $this->input->post('fail_percentage'),
                    'status' => 'active',
                    'created_by' => current_user_id()
                ];
                
                $campaign_id = $this->Campaign_model->create_campaign($campaign_data);
                
                if ($campaign_id) {
                    $this->Log_model->log_audit(current_user_id(), 'Create Campaign', 'Campaign Management', 'Created campaign: ' . $campaign_data['name']);
                    set_flash('success', 'Campaign created successfully.');
                    redirect('admin/campaign_view/' . $campaign_id);
                } else {
                    set_flash('error', 'Failed to create campaign.');
                }
            }
        }
        
        $this->load->view('admin/header', $data);
        $this->load->view('admin/campaigns/create', $data);
        $this->load->view('admin/footer');
    }

    /**
     * Campaign Management - View/Edit
     */
    public function campaign_view($id) {
        $data['page_title'] = 'Campaign Details';
        $data['campaign'] = $this->Campaign_model->get_by_id($id);
        
        if (!$data['campaign']) {
            set_flash('error', 'Campaign not found.');
            redirect('admin/campaigns');
        }
        
        // Get assigned users
        $data['assigned_users'] = $this->User_model->get_campaign_users($id);
        $data['available_users'] = $this->User_model->get_unassigned_users($id);
        
        $this->load->view('admin/header', $data);
        $this->load->view('admin/campaigns/view', $data);
        $this->load->view('admin/footer');
    }

    /**
     * Campaign Management - Edit
     */
    public function campaign_edit($id) {
        $data['page_title'] = 'Edit Campaign';
        $data['campaign'] = $this->Campaign_model->get_by_id($id);
        
        if (!$data['campaign']) {
            set_flash('error', 'Campaign not found.');
            redirect('admin/campaigns');
        }
        
        if ($this->input->method() == 'post') {
            $this->form_validation->set_rules('name', 'Campaign Name', 'required|trim');
            $this->form_validation->set_rules('type', 'Campaign Type', 'required|in_list[SMS,WhatsApp,WhatsApp Image,Status Messaging,Custom]');
            $this->form_validation->set_rules('fail_percentage', 'Fail Percentage', 'required|numeric|greater_than_equal_to[0.01]|less_than_equal_to[100]');
            
            if ($this->form_validation->run() === TRUE) {
                $update_data = [
                    'name' => $this->input->post('name'),
                    'type' => $this->input->post('type'),
                    'fail_percentage' => $this->input->post('fail_percentage')
                ];
                
                if ($this->Campaign_model->update_campaign($id, $update_data)) {
                    $this->Log_model->log_audit(current_user_id(), 'Update Campaign', 'Campaign Management', 'Updated campaign ID: ' . $id);
                    set_flash('success', 'Campaign updated successfully.');
                    redirect('admin/campaign_view/' . $id);
                } else {
                    set_flash('error', 'Failed to update campaign.');
                }
            }
        }
        
        $this->load->view('admin/header', $data);
        $this->load->view('admin/campaigns/edit', $data);
        $this->load->view('admin/footer');
    }

    /**
     * Campaign Management - Delete
     */
    public function campaign_delete($id) {
        $campaign = $this->Campaign_model->get_by_id($id);
        
        if (!$campaign) {
            set_flash('error', 'Campaign not found.');
        } elseif ($this->Campaign_model->delete_campaign($id)) {
            $this->Log_model->log_audit(current_user_id(), 'Delete Campaign', 'Campaign Management', 'Deleted campaign ID: ' . $id);
            set_flash('success', 'Campaign deleted successfully.');
        } else {
            set_flash('error', 'Failed to delete campaign.');
        }
        
        redirect('admin/campaigns');
    }

    /**
     * Campaign - Update Status
     */
    public function campaign_update_status($id) {
        $status = $this->input->post('status');
        
        if (in_array($status, ['active', 'paused', 'stopped', 'completed'])) {
            if ($this->Campaign_model->update_status($id, $status)) {
                $this->Log_model->log_audit(current_user_id(), 'Update Campaign Status', 'Campaign Management', "Campaign ID $id status changed to $status");
                echo json_encode(['success' => true, 'message' => 'Campaign status updated.']);
            } else {
                echo json_encode(['success' => false, 'message' => 'Failed to update status.']);
            }
        } else {
            echo json_encode(['success' => false, 'message' => 'Invalid status.']);
        }
    }

    /**
     * Campaign - Assign Users
     */
    public function campaign_assign_users($campaign_id) {
        $user_ids = $this->input->post('user_ids');
        
        if (empty($user_ids)) {
            echo json_encode(['success' => false, 'message' => 'No users selected.']);
            return;
        }
        
        if ($this->Campaign_model->assign_users($campaign_id, $user_ids)) {
            $this->Log_model->log_audit(current_user_id(), 'Assign Users', 'Campaign Management', "Assigned users to campaign ID $campaign_id");
            echo json_encode(['success' => true, 'message' => 'Users assigned successfully.']);
        } else {
            echo json_encode(['success' => false, 'message' => 'Failed to assign users.']);
        }
    }

    /**
     * Campaign - Assign Data to User
     */
    public function campaign_assign_data() {
        // Log start of function
        log_message('debug', 'campaign_assign_data called');
        
        $campaign_id = $this->input->post('campaign_id');
        $user_id = $this->input->post('user_id');
        $count = $this->input->post('count');
        
        // Log received data
        log_message('debug', "Received: campaign_id=$campaign_id, user_id=$user_id, count=$count");
        
        if (!$campaign_id || !$user_id || !$count) {
            echo json_encode(['success' => false, 'message' => 'Missing required fields.']);
            return;
        }
        
        $campaign = $this->Campaign_model->get_by_id($campaign_id);
        
        if (!$campaign) {
            echo json_encode(['success' => false, 'message' => 'Campaign not found.']);
            return;
        }
        
        if ($count < 1) {
            echo json_encode(['success' => false, 'message' => 'Please enter a valid number of records.']);
            return;
        }
        
        try {
            $result = $this->Data_model->assign_data_to_campaign($campaign_id, $user_id, $count, $campaign->fail_percentage);
            
            if (is_array($result) && isset($result['success']) && $result['success'] === true) {
                // Check if batch processing is required
                if (isset($result['batch_required']) && $result['batch_required']) {
                    echo json_encode([
                        'success' => true, 
                        'batch_required' => true,
                        'message' => 'Large dataset detected. Starting batch processing...',
                        'data' => $result
                    ]);
                    return;
                }
                
                $this->Campaign_model->update_counters($campaign_id);
                $this->Log_model->log_audit(current_user_id(), 'Assign Data', 'Campaign Management', "Assigned {$result['assigned_count']} data to user ID $user_id in campaign ID $campaign_id");
                echo json_encode(['success' => true, 'message' => 'Data assigned successfully.', 'data' => $result]);
            } else {
                $message = isset($result['message']) ? $result['message'] : 'Failed to assign data. Not enough unassigned data available.';
                echo json_encode(['success' => false, 'message' => $message]);
            }
        } catch (Exception $e) {
            log_message('error', 'Error in campaign_assign_data: ' . $e->getMessage());
            echo json_encode(['success' => false, 'message' => 'Server error: ' . $e->getMessage()]);
        }
    }
    
    /**
     * Campaign - Process batch data assignment
     * Called multiple times for large datasets
     */
    public function campaign_assign_data_batch() {
        log_message('debug', 'campaign_assign_data_batch called');
        
        $campaign_id = $this->input->post('campaign_id');
        $user_id = $this->input->post('user_id');
        $batch_size = (int) $this->input->post('batch_size') ?: 10000;
        $offset = (int) $this->input->post('offset') ?: 0;
        $total_count = (int) $this->input->post('total_count');
        $original_count = (int) $this->input->post('original_count');
        $fail_count = (int) $this->input->post('fail_count');
        
        if (!$campaign_id || !$user_id || !$total_count) {
            echo json_encode(['success' => false, 'message' => 'Missing required fields.']);
            return;
        }
        
        try {
            $result = $this->Data_model->process_assignment_batch($campaign_id, $user_id, $batch_size, $offset, $total_count);
            
            if ($result['success']) {
                // If completed, update counters and log
                if (isset($result['completed']) && $result['completed']) {
                    $this->Campaign_model->update_counters($campaign_id);
                    $this->Log_model->log_audit(
                        current_user_id(), 
                        'Assign Data (Batch)', 
                        'Campaign Management', 
                        "Assigned {$result['total_processed']} data to user ID $user_id in campaign ID $campaign_id"
                    );
                    $result['original_count'] = $original_count;
                    $result['fail_count'] = $fail_count;
                }
                
                echo json_encode($result);
            } else {
                echo json_encode($result);
            }
        } catch (Exception $e) {
            log_message('error', 'Error in campaign_assign_data_batch: ' . $e->getMessage());
            echo json_encode(['success' => false, 'message' => 'Server error: ' . $e->getMessage()]);
        }
    }

    /**
     * Message Scheduler - Create and List
     */
    public function message_schedules() {
        $data['page_title'] = 'Message Scheduler';
        $data['campaigns'] = $this->Campaign_model->get_all_campaigns(1000, 0);

        if ($this->input->method() === 'post') {
            $this->form_validation->set_rules('campaign_id', 'Campaign', 'required|integer');
            $this->form_validation->set_rules('total_recipients', 'Total Recipients', 'required|integer|greater_than_equal_to[4]');
            $this->form_validation->set_rules('message_content', 'Message Content', 'required|min_length[5]|max_length[2000]');
            $this->form_validation->set_rules('start_date', 'Start Date', 'required');
            $this->form_validation->set_rules('sender_id', 'Sender ID', 'required|trim|max_length[50]');

            if ($this->form_validation->run() === TRUE) {
                $campaign_id = (int) $this->input->post('campaign_id');
                $total_recipients = (int) $this->input->post('total_recipients');
                $message_content = $this->input->post('message_content', true);
                $start_date = $this->input->post('start_date');
                $sender_id = $this->input->post('sender_id', true);

                // Handle optional attachment upload (image or PDF)
                $attachmentPath = null;
                if (!empty($_FILES['attachment']) && $_FILES['attachment']['error'] === UPLOAD_ERR_OK) {
                    $uploadDir = FCPATH . 'uploads/attachments/';
                    if (!is_dir($uploadDir)) {
                        mkdir($uploadDir, 0755, true);
                    }

                    $fileTmp = $_FILES['attachment']['tmp_name'];
                    $origName = basename($_FILES['attachment']['name']);
                    $ext = strtolower(pathinfo($origName, PATHINFO_EXTENSION));
                    $fileSize = filesize($fileTmp);
                    $allowed = ['jpg','jpeg','png','gif','bmp','webp','pdf'];
                    $maxSize = 10 * 1024 * 1024; // 10MB

                    // Check extension
                    if (!in_array($ext, $allowed, true)) {
                        set_flash('error', 'Invalid file type. Allowed: images (jpg, png, gif, bmp, webp) and PDF.');
                        redirect('admin/message-schedules');
                    }

                    // Check file size
                    if ($fileSize > $maxSize) {
                        set_flash('error', 'File too large. Maximum 10MB allowed.');
                        redirect('admin/message-schedules');
                    }

                    // MIME type validation (content-based, not just extension)
                    $allowedMimes = ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/webp', 'application/pdf'];
                    $finfo = finfo_open(FILEINFO_MIME_TYPE);
                    $mimeType = finfo_file($finfo, $fileTmp);
                    finfo_close($finfo);

                    if (!in_array($mimeType, $allowedMimes, true)) {
                        set_flash('error', 'Invalid file format. MIME type: ' . htmlspecialchars($mimeType) . '. Only images and PDF allowed.');
                        redirect('admin/message-schedules');
                    }

                    // Safe filename: timestamp + random hex + extension
                    $safeName = time() . '_' . bin2hex(random_bytes(6)) . '.' . $ext;
                    $dest = $uploadDir . $safeName;

                    if (move_uploaded_file($fileTmp, $dest)) {
                        // store relative path
                        $attachmentPath = 'uploads/attachments/' . $safeName;
                    } else {
                        set_flash('error', 'Failed to move uploaded file.');
                        redirect('admin/message-schedules');
                    }
                }

                $campaign = $this->Campaign_model->get_by_id($campaign_id);

                if (!$campaign) {
                    set_flash('error', 'Selected campaign not found.');
                    redirect('admin/message-schedules');
                }

                $schedule = $this->Message_schedule_model->create_schedule(
                    $campaign_id,
                    current_user_id(),
                    $message_content,
                    $total_recipients,
                    4,
                    $start_date,
                    $sender_id,
                    $attachmentPath
                );

                if ($schedule) {
                    $this->Log_model->log_audit(current_user_id(), 'Create Message Schedule', 'Message Scheduler', 'Scheduled message for campaign ID ' . $campaign_id);
                    set_flash('success', 'Message schedule created successfully.');
                    redirect('admin/message-schedules');
                } else {
                    set_flash('error', 'Failed to create message schedule. Ensure total recipients is at least four.');
                    redirect('admin/message-schedules');
                }
            } else {
                set_flash('error', strip_tags(validation_errors()));
                redirect('admin/message-schedules');
            }
        }

        $schedules = $this->Message_schedule_model->get_schedules();

        foreach ($schedules as $schedule) {
            $schedule->table_id = 'batchTable_' . $schedule->id;
        }

        $grouped = [];

        foreach ($schedules as $schedule) {
            if (!isset($grouped[$schedule->campaign_id])) {
                $grouped[$schedule->campaign_id] = [
                    'campaign_name' => $schedule->campaign_name,
                    'campaign_id' => $schedule->campaign_id,
                    'campaign_type' => $schedule->campaign_type,
                    'schedules' => []
                ];
            }

            $grouped[$schedule->campaign_id]['schedules'][] = $schedule;
        }

        $data['schedules'] = $schedules;
        $data['grouped_schedules'] = $grouped;

        $this->load->view('admin/header', $data);
        $this->load->view('admin/messages/index', $data);
        $this->load->view('admin/footer');
    }

    public function message_batch_update_status($batch_id) {
        if ($this->input->method() !== 'post') {
            echo json_encode(['success' => false, 'message' => 'Invalid request method.']);
            return;
        }

        $status = $this->input->post('status');
        $allowed = ['pending', 'processing', 'sent'];

        if (!in_array($status, $allowed, true)) {
            echo json_encode(['success' => false, 'message' => 'Invalid status provided.']);
            return;
        }

        $batch = $this->db->where('id', $batch_id)->get('scheduled_message_batches')->row();

        if (!$batch) {
            echo json_encode(['success' => false, 'message' => 'Batch not found.']);
            return;
        }

        if ($this->Message_schedule_model->update_batch_status($batch_id, $status)) {
            $this->Log_model->log_audit(current_user_id(), 'Update Message Batch Status', 'Message Scheduler', 'Batch ' . $batch_id . ' status set to ' . $status);
            echo json_encode(['success' => true]);
        } else {
            echo json_encode(['success' => false, 'message' => 'Failed to update status.']);
        }
    }

    /**
     * Delete Schedule
     */
    public function delete_schedule($schedule_id) {
        if ($this->input->method() !== 'post') {
            echo json_encode(['success' => false, 'message' => 'Invalid request method.']);
            return;
        }

        $schedule = $this->db->where('id', $schedule_id)->get('scheduled_messages')->row();

        if (!$schedule) {
            echo json_encode(['success' => false, 'message' => 'Schedule not found.']);
            return;
        }

        // Delete associated attachment file if it exists
        if (!empty($schedule->attachment)) {
            $filePath = FCPATH . $schedule->attachment;
            if (file_exists($filePath) && is_file($filePath)) {
                if (@unlink($filePath)) {
                    log_message('info', 'Deleted attachment file: ' . $schedule->attachment);
                } else {
                    log_message('warning', 'Failed to delete attachment file: ' . $schedule->attachment);
                }
            }
        }

        // Delete schedule (CASCADE will delete batches automatically)
        $this->db->where('id', $schedule_id);
        if ($this->db->delete('scheduled_messages')) {
            $this->Log_model->log_audit(current_user_id(), 'Delete Schedule', 'Message Scheduler', 'Deleted schedule #' . $schedule_id);
            echo json_encode(['success' => true]);
        } else {
            echo json_encode(['success' => false, 'message' => 'Failed to delete schedule.']);
        }
    }

    /**
     * Master Data Management - List
     */
    public function master_data() {
        $data['page_title'] = 'Master Data Management';
        
        // For large datasets (2.1M+), use server-side processing
        // Only load initial page, rest loaded via AJAX
        $per_page = 50;
        $page = $this->input->get('page') ? $this->input->get('page') : 1;
        $offset = ($page - 1) * $per_page;
        
        $data['data_list'] = $this->Data_model->get_all_data($per_page, $offset);
        $data['total_data'] = $this->Data_model->count_data();
        $data['pagination'] = $this->_create_pagination($data['total_data'], $per_page, 'admin/master-data');
        $data['stats'] = $this->Data_model->get_dashboard_stats();
        $data['use_server_side'] = ($data['total_data'] > 10000); // Use server-side for large datasets
        
        $this->load->view('admin/header', $data);
        $this->load->view('admin/master_data/list', $data);
        $this->load->view('admin/footer');
    }
    
    /**
     * Master Data - Server-side DataTables AJAX endpoint (for 2.1M+ records)
     */
    public function master_data_ajax() {
        header('Content-Type: application/json');
        
        // DataTables parameters
        $draw = $this->input->get('draw');
        $start = (int)($this->input->get('start') ?? 0);
        $length = (int)($this->input->get('length') ?? 50);
        $search = $this->input->get('search');
        $search_value = isset($search['value']) ? $search['value'] : '';
        $order = $this->input->get('order');
        
        // Columns for ordering
        $columns = ['id', 'mobile', 'name', 'email', 'address', 'is_assigned', 'uploaded_at'];
        $order_column = isset($order[0]['column']) ? $columns[$order[0]['column']] : 'id';
        $order_dir = isset($order[0]['dir']) && $order[0]['dir'] == 'asc' ? 'ASC' : 'DESC';
        
        // Get total count (cached for performance)
        $total_records = $this->Data_model->count_data();
        
        // Build filtered query
        $this->db->from('master_data');
        
        if (!empty($search_value)) {
            $this->db->group_start();
            $this->db->like('mobile', $search_value);
            $this->db->or_like('name', $search_value);
            $this->db->or_like('email', $search_value);
            $this->db->group_end();
        }
        
        // Get filtered count
        $filtered_records = $this->db->count_all_results('', false);
        
        // Get data
        $this->db->order_by($order_column, $order_dir);
        $this->db->limit($length, $start);
        $records = $this->db->get()->result();
        
        // Format data for DataTables
        $data = [];
        foreach ($records as $idx => $record) {
            $data[] = [
                $record->id,
                $record->mobile,
                $record->name ?? '',
                $record->email ?? '',
                substr($record->address ?? '', 0, 50) . (strlen($record->address ?? '') > 50 ? '...' : ''),
                $record->is_assigned ? '<span class="badge bg-success">Assigned</span>' : '<span class="badge bg-secondary">Not Assigned</span>',
                date('M d, Y H:i', strtotime($record->uploaded_at))
            ];
        }
        
        echo json_encode([
            'draw' => intval($draw),
            'recordsTotal' => $total_records,
            'recordsFiltered' => $filtered_records,
            'data' => $data
        ]);
    }

    /**
     * Master Data - Get total count for export
     */
    public function master_data_count() {
        header('Content-Type: application/json');
        
        $count = $this->Data_model->count_data();
        
        echo json_encode([
            'success' => true,
            'count' => $count
        ]);
    }

    /**
     * Master Data - Export batch for large dataset (3M+ records)
     * Returns data in JSON format for client-side CSV generation
     */
    public function master_data_export_batch() {
        set_time_limit(300);
        ini_set('memory_limit', '512M');
        
        header('Content-Type: application/json');
        header('Cache-Control: no-cache, must-revalidate');
        
        $offset = (int)($this->input->get('offset') ?? 0);
        $limit = (int)($this->input->get('limit') ?? 50000);
        
        // Limit batch size to prevent memory issues
        $limit = min($limit, 100000);
        
        try {
            // Fetch data directly with minimal overhead
            $this->db->select('id, mobile, name, email, address, custom_field1, custom_field2, custom_field3, is_assigned, uploaded_at');
            $this->db->limit($limit, $offset);
            $this->db->order_by('id', 'ASC');
            $records = $this->db->get('master_data')->result_array();
            
            echo json_encode([
                'success' => true,
                'data' => $records,
                'count' => count($records),
                'offset' => $offset,
                'limit' => $limit
            ]);
            
        } catch (Exception $e) {
            log_message('error', 'Export batch error: ' . $e->getMessage());
            echo json_encode([
                'success' => false,
                'message' => 'Error fetching data: ' . $e->getMessage()
            ]);
        }
    }

    /**
     * Master Data - Upload CSV/Excel
     */
    public function master_data_upload() {
        if ($this->input->method() != 'post') {
            echo json_encode(['success' => false, 'message' => 'Invalid request method.']);
            return;
        }
        
        $config['upload_path'] = './uploads/';
        $config['allowed_types'] = 'csv|xls|xlsx';
        $config['max_size'] = 10240; // 10MB
        
        if (!is_dir($config['upload_path'])) {
            mkdir($config['upload_path'], 0777, TRUE);
        }
        
        $this->upload->initialize($config);
        
        if (!$this->upload->do_upload('data_file')) {
            echo json_encode(['success' => false, 'message' => $this->upload->display_errors('', '')]);
            return;
        }
        
        $file_data = $this->upload->data();
        $file_path = $file_data['full_path'];
        
        // Parse CSV
        $data_array = $this->_parse_csv($file_path);
        
        if (empty($data_array)) {
            unlink($file_path);
            echo json_encode(['success' => false, 'message' => 'No valid data found in file.']);
            return;
        }
        
        // Insert data
        if ($this->Data_model->insert_bulk_data($data_array)) {
            $this->Log_model->log_audit(current_user_id(), 'Upload Master Data', 'Master Data', 'Uploaded ' . count($data_array) . ' records');
            unlink($file_path);
            echo json_encode(['success' => true, 'message' => count($data_array) . ' records uploaded successfully.']);
        } else {
            unlink($file_path);
            echo json_encode(['success' => false, 'message' => 'Failed to upload data.']);
        }
    }

    /**
     * Parse CSV file
     */
    private function _parse_csv($file_path) {
        $data_array = [];
        
        if (($handle = fopen($file_path, 'r')) !== FALSE) {
            $header = fgetcsv($handle); // Read header row
            
            while (($row = fgetcsv($handle)) !== FALSE) {
                if (count($row) >= 1 && !empty($row[0])) {
                    $data_array[] = [
                        'mobile' => isset($row[0]) ? trim($row[0]) : '',
                        'name' => isset($row[1]) ? trim($row[1]) : '',
                        'email' => isset($row[2]) ? trim($row[2]) : '',
                        'address' => isset($row[3]) ? trim($row[3]) : '',
                        'custom_field1' => isset($row[4]) ? trim($row[4]) : '',
                        'custom_field2' => isset($row[5]) ? trim($row[5]) : '',
                        'custom_field3' => isset($row[6]) ? trim($row[6]) : ''
                    ];
                }
            }
            
            fclose($handle);
        }
        
        return $data_array;
    }
    
    /**
     * Parse CSV file in batches for large files (2.1M+ records)
     * Generator-based to minimize memory usage
     */
    private function _parse_csv_generator($file_path, $batch_size = 10000) {
        if (($handle = fopen($file_path, 'r')) !== FALSE) {
            $header = fgetcsv($handle); // Read header row
            $batch = [];
            $count = 0;
            
            while (($row = fgetcsv($handle)) !== FALSE) {
                if (count($row) >= 1 && !empty($row[0])) {
                    $batch[] = [
                        'mobile' => isset($row[0]) ? trim($row[0]) : '',
                        'name' => isset($row[1]) ? trim($row[1]) : '',
                        'email' => isset($row[2]) ? trim($row[2]) : '',
                        'address' => isset($row[3]) ? trim($row[3]) : '',
                        'custom_field1' => isset($row[4]) ? trim($row[4]) : '',
                        'custom_field2' => isset($row[5]) ? trim($row[5]) : '',
                        'custom_field3' => isset($row[6]) ? trim($row[6]) : ''
                    ];
                    $count++;
                    
                    if ($count >= $batch_size) {
                        yield $batch;
                        $batch = [];
                        $count = 0;
                    }
                }
            }
            
            // Yield remaining batch
            if (!empty($batch)) {
                yield $batch;
            }
            
            fclose($handle);
        }
    }
    
    /**
     * Master Data - Large file upload with batch processing (2.1M+ records)
     */
    public function master_data_upload_large() {
        set_time_limit(0);
        ini_set('memory_limit', '1024M');
        
        if ($this->input->method() != 'post') {
            echo json_encode(['success' => false, 'message' => 'Invalid request method.']);
            return;
        }
        
        $config['upload_path'] = './uploads/';
        $config['allowed_types'] = 'csv';
        $config['max_size'] = 102400; // 100MB for large files
        
        if (!is_dir($config['upload_path'])) {
            mkdir($config['upload_path'], 0777, TRUE);
        }
        
        $this->upload->initialize($config);
        
        if (!$this->upload->do_upload('data_file')) {
            echo json_encode(['success' => false, 'message' => $this->upload->display_errors('', '')]);
            return;
        }
        
        $file_data = $this->upload->data();
        $file_path = $file_data['full_path'];
        
        // Count total lines first
        $line_count = 0;
        $handle = fopen($file_path, 'r');
        while (!feof($handle)) {
            fgets($handle);
            $line_count++;
        }
        fclose($handle);
        $line_count--; // Subtract header
        
        $total_inserted = 0;
        $batch_num = 0;
        $batch_size = 10000;
        $total_batches = ceil($line_count / $batch_size);
        
        // Process in batches using generator
        foreach ($this->_parse_csv_generator($file_path, $batch_size) as $batch) {
            $batch_num++;
            $result = $this->Data_model->insert_bulk_data_batch($batch, $batch_num, $total_batches);
            if ($result['success']) {
                $total_inserted += $result['inserted'];
            }
            
            // Free memory
            unset($batch);
            gc_collect_cycles();
        }
        
        $this->Log_model->log_audit(current_user_id(), 'Upload Master Data (Large)', 'Master Data', 'Uploaded ' . $total_inserted . ' records from ' . number_format($line_count) . ' rows');
        unlink($file_path);
        
        echo json_encode([
            'success' => true, 
            'message' => number_format($total_inserted) . ' records uploaded successfully from ' . number_format($line_count) . ' rows.',
            'total_processed' => $line_count,
            'total_inserted' => $total_inserted
        ]);
    }

    /**
     * Reports
     */
    public function reports() {
        $data['page_title'] = 'Reports';
        
        // Get all campaigns with stats
        $data['campaigns'] = $this->Campaign_model->get_all_campaigns(100, 0);
        
        // Get overall statistics
        $data['total_campaigns'] = $this->Campaign_model->count_campaigns();
        $data['active_campaigns'] = $this->Campaign_model->count_campaigns('active');
        $data['total_users'] = $this->User_model->count_users('user');
        $data['total_master_data'] = $this->Data_model->count_data();
        
        // Get performance data
        $data['performance_data'] = $this->Campaign_model->get_performance_chart_data(30);
        
        // Get top performing campaigns
        $data['top_campaigns'] = $this->db->select('campaigns.*, 
            CASE 
                WHEN total_assigned > 0 THEN ROUND((total_sent / total_assigned) * 100, 2)
                ELSE 0
            END as success_rate')
            ->from('campaigns')
            ->where('total_assigned >', 0)
            ->order_by('success_rate', 'DESC')
            ->limit(5)
            ->get()
            ->result();
        
        $this->load->view('admin/header', $data);
        $this->load->view('admin/reports/index', $data);
        $this->load->view('admin/footer');
    }

    /**
     * Login Logs
     */
    public function login_logs() {
        $data['page_title'] = 'Login Logs';
        
        // Pagination
        $per_page = 20;
        $page = $this->input->get('page') ? $this->input->get('page') : 1;
        $offset = ($page - 1) * $per_page;
        
        $data['logs'] = $this->Log_model->get_login_logs($per_page, $offset);
        $data['total_logs'] = $this->Log_model->count_login_logs();
        $data['pagination'] = $this->_create_pagination($data['total_logs'], $per_page, 'admin/login-logs');
        
        $this->load->view('admin/header', $data);
        $this->load->view('admin/logs/login_logs', $data);
        $this->load->view('admin/footer');
    }

    /**
     * Activity Logs
     */
    public function activity_logs() {
        $data['page_title'] = 'Activity Logs';
        
        // Pagination
        $per_page = 20;
        $page = $this->input->get('page') ? $this->input->get('page') : 1;
        $offset = ($page - 1) * $per_page;
        
        $data['logs'] = $this->Log_model->get_audit_logs($per_page, $offset);
        $data['total_logs'] = $this->Log_model->count_audit_logs();
        $data['pagination'] = $this->_create_pagination($data['total_logs'], $per_page, 'admin/activity-logs');
        
        $this->load->view('admin/header', $data);
        $this->load->view('admin/logs/activity_logs', $data);
        $this->load->view('admin/footer');
    }

    /**
     * Admin Profile Management
     */
    public function profile() {
        $data['page_title'] = 'My Profile';
        $data['user'] = $this->User_model->get_by_id(current_user_id());
        
        if ($this->input->method() == 'post') {
            $this->form_validation->set_rules('username', 'Username', 'required|trim');
            $this->form_validation->set_rules('email', 'Email', 'required|valid_email');
            
            if ($this->input->post('new_password')) {
                $this->form_validation->set_rules('new_password', 'New Password', 'min_length[6]');
                $this->form_validation->set_rules('confirm_password', 'Confirm Password', 'matches[new_password]');
            }
            
            if ($this->form_validation->run() === TRUE) {
                $update_data = [
                    'username' => $this->input->post('username'),
                    'email' => $this->input->post('email')
                ];
                
                if ($this->input->post('new_password')) {
                    $update_data['password'] = $this->input->post('new_password');
                }
                
                if ($this->User_model->update_user(current_user_id(), $update_data)) {
                    $this->Log_model->log_audit(current_user_id(), 'Update Profile', 'Profile Management', 'Updated own profile');
                    set_flash('success', 'Profile updated successfully.');
                    redirect('admin/profile');
                } else {
                    set_flash('error', 'Failed to update profile.');
                }
            }
        }
        
        $this->load->view('admin/header', $data);
        $this->load->view('admin/profile', $data);
        $this->load->view('admin/footer');
    }

    /**
     * Create pagination helper
     */
    private function _create_pagination($total_rows, $per_page, $base_url) {
        return [
            'total_rows' => $total_rows,
            'per_page' => $per_page,
            'total_pages' => ceil($total_rows / $per_page),
            'current_page' => $this->input->get('page') ? $this->input->get('page') : 1,
            'base_url' => base_url($base_url)
        ];
    }
}
