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

class Send_model extends CI_Model {

    public function __construct() {
        parent::__construct();
    }

    /**
     * Simulate sending message with fail logic
     */
    public function send_message($campaign_id, $user_id, $cud_id, $message_content) {
        // Get campaign to check fail percentage
        $this->db->select('fail_percentage');
        $campaign = $this->db->get_where('campaigns', ['id' => $campaign_id])->row();
        
        if (!$campaign) {
            return false;
        }
        
        // Get campaign user data
        $this->db->select('campaign_user_data.*, master_data.mobile');
        $this->db->from('campaign_user_data');
        $this->db->join('master_data', 'master_data.id = campaign_user_data.master_data_id');
        $this->db->where('campaign_user_data.id', $cud_id);
        $data = $this->db->get()->row();
        
        if (!$data) {
            return false;
        }
        
        // Simulate send with random fail based on fail_percentage
        // Generate random number between 0 and 100 with decimals
        $random = mt_rand(0, 10000) / 100; // 0.00 to 100.00
        $will_fail = ($random < $campaign->fail_percentage);
        
        $status = $will_fail ? 'failed' : 'sent';
        $error_message = $will_fail ? 'Simulated network failure (Random: ' . number_format($random, 2) . '% < ' . $campaign->fail_percentage . '%)' : null;
        
        $this->db->trans_start();
        
        // Update campaign_user_data status
        $this->db->where('id', $cud_id);
        $this->db->update('campaign_user_data', [
            'status' => $status,
            'message_content' => $message_content,
            'sent_at' => date('Y-m-d H:i:s')
        ]);
        
        // Insert into send_logs
        $this->db->insert('send_logs', [
            'campaign_id' => $campaign_id,
            'user_id' => $user_id,
            'campaign_data_id' => $cud_id,
            'mobile' => $data->mobile,
            'message_content' => $message_content,
            'status' => $status,
            'error_message' => $error_message,
            'ip_address' => $this->input->ip_address(),
            'user_agent' => $this->input->user_agent()
        ]);
        
        $new_cud_id = null;
        
        // If failed, auto-add new data and send to it immediately
        if ($will_fail) {
            $this->load->model('Data_model');
            $new_cud_id = $this->Data_model->auto_add_on_fail($campaign_id, $user_id, $data->master_data_id);
            
            // If new data was added, send message to it immediately
            if ($new_cud_id) {
                // Get the new data
                $this->db->select('campaign_user_data.*, master_data.mobile');
                $this->db->from('campaign_user_data');
                $this->db->join('master_data', 'master_data.id = campaign_user_data.master_data_id');
                $this->db->where('campaign_user_data.id', $new_cud_id);
                $new_data = $this->db->get()->row();
                
                if ($new_data) {
                    // Send to new data (this one will succeed)
                    $this->db->where('id', $new_cud_id);
                    $this->db->update('campaign_user_data', [
                        'status' => 'sent',
                        'message_content' => $message_content,
                        'sent_at' => date('Y-m-d H:i:s')
                    ]);
                    
                    // Log the successful send
                    $this->db->insert('send_logs', [
                        'campaign_id' => $campaign_id,
                        'user_id' => $user_id,
                        'campaign_data_id' => $new_cud_id,
                        'mobile' => $new_data->mobile,
                        'message_content' => $message_content,
                        'status' => 'sent',
                        'error_message' => null,
                        'ip_address' => $this->input->ip_address(),
                        'user_agent' => $this->input->user_agent()
                    ]);
                }
            }
        }
        
        $this->db->trans_complete();
        
        if ($this->db->trans_status()) {
            // Update campaign counters
            $this->load->model('Campaign_model');
            $this->Campaign_model->update_counters($campaign_id);
            
            return [
                'success' => true,
                'status' => $status,
                'message' => $status == 'sent' ? 'Message sent successfully' : 'Message failed - new data added and sent',
                'auto_added' => $will_fail,
                'new_cud_id' => $new_cud_id
            ];
        }
        
        return false;
    }

    /**
     * Get send logs for campaign
     */
    public function get_send_logs($campaign_id, $user_id = null, $limit = 10, $offset = 0) {
        $this->db->select('send_logs.*, users.username');
        $this->db->from('send_logs');
        $this->db->join('users', 'users.id = send_logs.user_id');
        $this->db->where('send_logs.campaign_id', $campaign_id);
        
        if ($user_id) {
            $this->db->where('send_logs.user_id', $user_id);
        }
        
        $this->db->limit($limit, $offset);
        $this->db->order_by('send_logs.created_at', 'DESC');
        
        return $this->db->get()->result();
    }

    /**
     * Count send logs
     */
    public function count_send_logs($campaign_id, $user_id = null) {
        $this->db->from('send_logs');
        $this->db->where('campaign_id', $campaign_id);
        
        if ($user_id) {
            $this->db->where('user_id', $user_id);
        }
        
        return $this->db->count_all_results();
    }

    /**
     * Get user activity stats
     */
    public function get_user_activity_stats($user_id, $campaign_id = null) {
        $this->db->select('COUNT(*) as total, 
                          SUM(CASE WHEN status = "sent" THEN 1 ELSE 0 END) as sent,
                          SUM(CASE WHEN status = "failed" THEN 1 ELSE 0 END) as failed');
        $this->db->from('send_logs');
        $this->db->where('user_id', $user_id);
        
        if ($campaign_id) {
            $this->db->where('campaign_id', $campaign_id);
        }
        
        return $this->db->get()->row();
    }

    /**
     * Get today's activity for user
     */
    public function get_today_activity($user_id) {
        $this->db->select('COUNT(*) as total,
                          SUM(CASE WHEN status = "sent" THEN 1 ELSE 0 END) as sent,
                          SUM(CASE WHEN status = "failed" THEN 1 ELSE 0 END) as failed');
        $this->db->from('send_logs');
        $this->db->where('user_id', $user_id);
        $this->db->where('DATE(created_at)', date('Y-m-d'));
        
        return $this->db->get()->row();
    }

    /**
     * Get auto-added data history
     */
    public function get_auto_add_history($campaign_id, $limit = 10, $offset = 0) {
        $this->db->select('fail_auto_add.*, users.username');
        $this->db->from('fail_auto_add');
        $this->db->join('users', 'users.id = fail_auto_add.user_id');
        $this->db->where('fail_auto_add.campaign_id', $campaign_id);
        $this->db->limit($limit, $offset);
        $this->db->order_by('fail_auto_add.created_at', 'DESC');
        
        return $this->db->get()->result();
    }

    /**
     * Get hourly activity data for charts
     */
    public function get_hourly_activity($user_id, $date = null) {
        if (!$date) {
            $date = date('Y-m-d');
        }
        
        $this->db->select('HOUR(created_at) as hour,
                          COUNT(*) as total,
                          SUM(CASE WHEN status = "sent" THEN 1 ELSE 0 END) as sent,
                          SUM(CASE WHEN status = "failed" THEN 1 ELSE 0 END) as failed');
        $this->db->from('send_logs');
        $this->db->where('user_id', $user_id);
        $this->db->where('DATE(created_at)', $date);
        $this->db->group_by('HOUR(created_at)');
        $this->db->order_by('hour', 'ASC');
        
        return $this->db->get()->result();
    }
    
    /**
     * Bulk send messages - Optimized for 2.1M+ records
     * Processes in batches with transaction management
     */
    public function bulk_send_batch($campaign_id, $user_id, $cud_ids, $message_content, $fail_percentage) {
        set_time_limit(300);
        ini_set('memory_limit', '512M');
        
        if (empty($cud_ids)) {
            return ['success' => false, 'message' => 'No data to process'];
        }
        
        $total = count($cud_ids);
        $sent = 0;
        $failed = 0;
        $timestamp = date('Y-m-d H:i:s');
        
        $this->db->trans_start();
        
        // Process in smaller chunks to avoid timeout
        $chunks = array_chunk($cud_ids, 1000);
        
        foreach ($chunks as $chunk) {
            foreach ($chunk as $cud_id) {
                // Simulate send with random fail
                $random = mt_rand(0, 10000) / 100;
                $will_fail = ($random < $fail_percentage);
                $status = $will_fail ? 'failed' : 'sent';
                
                if ($will_fail) {
                    $failed++;
                } else {
                    $sent++;
                }
            }
            
            // Bulk update status
            $sent_ids = [];
            $failed_ids = [];
            
            foreach ($chunk as $idx => $cud_id) {
                $random = mt_rand(0, 10000) / 100;
                if ($random < $fail_percentage) {
                    $failed_ids[] = $cud_id;
                } else {
                    $sent_ids[] = $cud_id;
                }
            }
            
            if (!empty($sent_ids)) {
                $this->db->where_in('id', $sent_ids);
                $this->db->update('campaign_user_data', [
                    'status' => 'sent',
                    'message_content' => $message_content,
                    'sent_at' => $timestamp
                ]);
            }
            
            if (!empty($failed_ids)) {
                $this->db->where_in('id', $failed_ids);
                $this->db->update('campaign_user_data', [
                    'status' => 'failed',
                    'message_content' => $message_content,
                    'sent_at' => $timestamp
                ]);
            }
        }
        
        $this->db->trans_complete();
        
        if ($this->db->trans_status()) {
            // Update campaign counters
            $this->load->model('Campaign_model');
            $this->Campaign_model->update_counters($campaign_id);
            
            return [
                'success' => true,
                'total' => $total,
                'sent' => $sent,
                'failed' => $failed
            ];
        }
        
        return ['success' => false, 'message' => 'Database transaction failed'];
    }
    
    /**
     * Get send statistics for large campaigns - Uses SQL aggregation
     */
    public function get_campaign_stats_optimized($campaign_id) {
        $sql = "SELECT 
                    COUNT(*) as total,
                    SUM(CASE WHEN status = 'sent' THEN 1 ELSE 0 END) as sent,
                    SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed,
                    SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending
                FROM campaign_user_data
                WHERE campaign_id = ?";
        
        return $this->db->query($sql, [$campaign_id])->row();
    }
}
