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

class Whatsapp_model extends CI_Model {

    protected $templates_table = 'db_whatsapp_templates';
    protected $logs_table = 'db_whatsapp_logs';
    
    protected $templates_column_order = array(null, 'template_name', 'template_type', 'template_subject', 'template_content', 'status', null);
    protected $templates_column_search = array('template_name', 'template_type', 'template_subject', 'template_content');
    protected $templates_order = array('id' => 'desc');
    
    protected $logs_column_order = array(null, 'phone_number', 'message_type', 'message_content', 'status', 'sent_at', null);
    protected $logs_column_search = array('phone_number', 'message_type', 'message_content', 'status');
    protected $logs_order = array('id' => 'desc');

    public function __construct() {
        parent::__construct();
        $this->data = array();
    }

    // Test API Connection
    public function test_api_connection($store_details) {
        if(empty($store_details->whatsapp_api_url) || empty($store_details->whatsapp_api_key) || empty($store_details->whatsapp_instance_id)) {
            return ['status' => 'error', 'message' => 'API URL, Access Token and Instance ID are required'];
        }

        // Simple connectivity test - just check if the API endpoint is reachable
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $store_details->whatsapp_api_url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_NOBODY, true); // HEAD request instead of POST
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curl_error = curl_error($ch);
        curl_close($ch);

        if($curl_error) {
            return ['status' => 'error', 'message' => 'Connection failed: ' . $curl_error];
        }

        // Accept various HTTP codes that indicate the endpoint exists
        if(in_array($http_code, [200, 201, 400, 401, 403, 405, 422])) {
            return [
                'status' => 'success', 
                'message' => 'Connection successful! API endpoint is reachable. Instance ID: ' . $store_details->whatsapp_instance_id
            ];
        } else {
            return ['status' => 'error', 'message' => 'API endpoint returned HTTP ' . $http_code . ' - may not be accessible'];
        }
    }

    // Send WhatsApp Message with optional media
    public function send_message($phone_number, $message, $message_type = 'manual', $reference_id = null, $reference_type = null, $customer_id = null, $media_url = null, $media_type = 'text') {
        $store_details = get_store_details();
        
        if($store_details->whatsapp_status != 1) {
            return ['status' => 'error', 'message' => 'WhatsApp is not enabled'];
        }

        // Clean phone number
        $phone_number = $this->clean_phone_number($phone_number);
        
        // Prepare API payload according to documentation
        $payload = [
            'number' => $phone_number,
            'type' => $media_type,
            'instance_id' => $store_details->whatsapp_instance_id,
            'access_token' => $store_details->whatsapp_api_key
        ];

        // Add message content based on type
        if ($media_type === 'text') {
            $payload['message'] = $message;
        } elseif ($media_type === 'media' && !empty($media_url)) {
            $payload['media_url'] = $media_url;
            $payload['caption'] = $message;
        } else {
            $payload['message'] = $message;
        }

        // Send to API
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $store_details->whatsapp_api_url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json'
        ]);

        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curl_error = curl_error($ch);
        curl_close($ch);

        // Log the message
        $log_data = [
            'store_id' => get_current_store_id(),
            'customer_id' => $customer_id,
            'phone_number' => $phone_number,
            'message_type' => $message_type,
            'message_content' => $message,
            'reference_id' => $reference_id,
            'reference_type' => $reference_type,
            'status' => ($http_code === 200) ? 'sent' : 'failed',
            'response_data' => $response,
            'error_message' => $curl_error,
            'sent_at' => date('Y-m-d H:i:s'),
            'created_date' => date('Y-m-d'),
            'created_time' => date('H:i:s'),
            'created_by' => $this->session->userdata('inv_username') ?? 'System',
            'system_ip' => $this->input->ip_address(),
            'system_name' => gethostname()
        ];

        $this->db->insert($this->logs_table, $log_data);

        if($curl_error) {
            return ['status' => 'error', 'message' => 'Failed to send: ' . $curl_error];
        }

        if($http_code === 200) {
            return ['status' => 'success', 'message' => 'Message sent successfully', 'response' => json_decode($response, true)];
        } else {
            return ['status' => 'error', 'message' => 'API returned HTTP ' . $http_code, 'response' => $response];
        }
    }

    // Clean phone number format
    private function clean_phone_number($phone) {
        // Remove all non-numeric characters
        $phone = preg_replace('/[^0-9]/', '', $phone);
        
        // Add country code if not present (assuming India +91)
        if(strlen($phone) === 10) {
            $phone = '91' . $phone;
        }
        
        return $phone;
    }

    // Send message using template
    public function send_template_message($customer_id, $template_type, $variables = []) {
        // Get customer details
        $this->db->where('id', $customer_id);
        $customer = $this->db->get('db_customers')->row();
        
        if(!$customer || empty($customer->mobile)) {
            return ['status' => 'error', 'message' => 'Customer not found or no mobile number'];
        }

        // Get template
        $this->db->where('store_id', get_current_store_id());
        $this->db->where('template_type', $template_type);
        $this->db->where('status', 1);
        $template = $this->db->get($this->templates_table)->row();

        if(!$template) {
            return ['status' => 'error', 'message' => 'Template not found'];
        }

        // Replace variables in template
        $message = $this->replace_template_variables($template->template_content, $variables);

        // Send message
        return $this->send_message(
            $customer->mobile,
            $message,
            $template_type,
            $variables['reference_id'] ?? null,
            $variables['reference_type'] ?? null,
            $customer_id
        );
    }

    // Replace template variables
    private function replace_template_variables($content, $variables) {
        $store_details = get_store_details();
        
        // Default variables
        $default_vars = [
            'BUSINESS_NAME' => $store_details->whatsapp_business_name ?? $store_details->store_name,
            'STORE_NAME' => $store_details->store_name,
            'STORE_ADDRESS' => $store_details->address,
            'STORE_PHONE' => $store_details->mobile,
            'STORE_EMAIL' => $store_details->email
        ];
        
        $all_variables = array_merge($default_vars, $variables);
        
        foreach($all_variables as $key => $value) {
            $content = str_replace('{' . $key . '}', $value, $content);
        }
        
        return $content;
    }

    // Get Templates
    public function get_templates($type = null) {
        $this->db->where('store_id', get_current_store_id());
        $this->db->where('status', 1);
        
        if($type) {
            $this->db->where('template_type', $type);
        }
        
        return $this->db->get($this->templates_table)->result();
    }

    // Get Template by ID
    public function get_template($id) {
        $this->db->where('id', $id);
        $this->db->where('store_id', get_current_store_id());
        return $this->db->get($this->templates_table)->row();
    }

    // DataTables for Templates
    private function _get_templates_datatables_query() {
        $this->db->from($this->templates_table);
        $this->db->where("store_id", get_current_store_id());

        $i = 0;
        foreach ($this->templates_column_search as $item) {
            if ($_POST['search']['value']) {
                if ($i === 0) {
                    $this->db->group_start();
                    $this->db->like($item, $_POST['search']['value']);
                } else {
                    $this->db->or_like($item, $_POST['search']['value']);
                }

                if (count($this->templates_column_search) - 1 == $i) {
                    $this->db->group_end();
                }
            }
            $i++;
        }

        if (isset($_POST['order'])) {
            $this->db->order_by($this->templates_column_order[$_POST['order']['0']['column']], $_POST['order']['0']['dir']);
        } else if (isset($this->templates_order)) {
            $order = $this->templates_order;
            $this->db->order_by(key($order), $order[key($order)]);
        }
    }

    function get_templates_datatables() {
        $this->_get_templates_datatables_query();
        if ($_POST['length'] != -1) {
            $this->db->limit($_POST['length'], $_POST['start']);
        }
        $query = $this->db->get();
        return $query->result();
    }

    function count_filtered_templates() {
        $this->_get_templates_datatables_query();
        $query = $this->db->get();
        return $query->num_rows();
    }

    public function count_all_templates() {
        $this->db->where("store_id", get_current_store_id());
        $this->db->from($this->templates_table);
        return $this->db->count_all_results();
    }

    // Update Template
    public function update_template() {
        extract($this->security->xss_clean(html_escape(array_merge($this->data, $_POST))));
        
        $info = array(
            'template_name' => $template_name,
            'template_subject' => $template_subject ?? '',
            'template_content' => $template_content,
            'updated_date' => date('Y-m-d'),
            'updated_time' => date('H:i:s'),
            'updated_by' => $this->session->userdata('inv_username')
        );

        $result = $this->db->where('id', $template_id)
                          ->where('store_id', get_current_store_id())
                          ->update($this->templates_table, $info);

        if ($result) {
            $this->session->set_flashdata('success', 'Template updated successfully!');
            return "success";
        } else {
            return "failed";
        }
    }

    // Update Template Status
    public function update_template_status($id, $status) {
        if (set_status_of_table($id, $status, $this->templates_table)) {
            echo "success";
        } else {
            echo "failed";
        }
    }

    // Delete Template
    public function delete_template($id) {
        // Check if it's a default template
        $this->db->where('id', $id);
        $this->db->where('store_id', get_current_store_id());
        $template = $this->db->get($this->templates_table)->row();
        
        if($template && $template->is_default == 1) {
            echo "Cannot delete default template";
            return;
        }

        $this->db->where("id", $id);
        $this->db->where("store_id", get_current_store_id());
        $query = $this->db->delete($this->templates_table);
        
        if ($query) {
            echo "success";
        } else {
            echo "failed";
        }
    }

    // DataTables for Logs
    private function _get_logs_datatables_query() {
        $this->db->from($this->logs_table);
        $this->db->where("store_id", get_current_store_id());

        $i = 0;
        foreach ($this->logs_column_search as $item) {
            if ($_POST['search']['value']) {
                if ($i === 0) {
                    $this->db->group_start();
                    $this->db->like($item, $_POST['search']['value']);
                } else {
                    $this->db->or_like($item, $_POST['search']['value']);
                }

                if (count($this->logs_column_search) - 1 == $i) {
                    $this->db->group_end();
                }
            }
            $i++;
        }

        if (isset($_POST['order'])) {
            $this->db->order_by($this->logs_column_order[$_POST['order']['0']['column']], $_POST['order']['0']['dir']);
        } else if (isset($this->logs_order)) {
            $order = $this->logs_order;
            $this->db->order_by(key($order), $order[key($order)]);
        }
    }

    function get_logs_datatables() {
        $this->_get_logs_datatables_query();
        if ($_POST['length'] != -1) {
            $this->db->limit($_POST['length'], $_POST['start']);
        }
        $query = $this->db->get();
        return $query->result();
    }

    function count_filtered_logs() {
        $this->_get_logs_datatables_query();
        $query = $this->db->get();
        return $query->num_rows();
    }

    public function count_all_logs() {
        $this->db->where("store_id", get_current_store_id());
        $this->db->from($this->logs_table);
        return $this->db->count_all_results();
    }

    // Get Log by ID
    public function get_log($id) {
        $this->db->where('id', $id);
        $this->db->where('store_id', get_current_store_id());
        return $this->db->get($this->logs_table)->row();
    }

    // Send Bulk Messages
    public function send_bulk_messages($template_id, $customer_ids) {
        $template = $this->get_template($template_id);
        if(!$template) {
            return ['status' => 'error', 'message' => 'Template not found'];
        }

        $success_count = 0;
        $failed_count = 0;
        $results = [];

        foreach($customer_ids as $customer_id) {
            // Get customer details
            $this->db->where('id', $customer_id);
            $customer = $this->db->get('db_customers')->row();
            
            if(!$customer || empty($customer->mobile)) {
                $failed_count++;
                continue;
            }

            // Prepare variables
            $variables = [
                'CUSTOMER_NAME' => $customer->customer_name,
                'CUSTOMER_CODE' => $customer->customer_code,
                'CUSTOMER_MOBILE' => $customer->mobile,
                'CUSTOMER_EMAIL' => $customer->email
            ];

            // Replace variables and send
            $message = $this->replace_template_variables($template->template_content, $variables);
            $result = $this->send_message(
                $customer->mobile,
                $message,
                'bulk',
                $template_id,
                'template',
                $customer_id
            );

            if($result['status'] === 'success') {
                $success_count++;
            } else {
                $failed_count++;
            }
            
            $results[] = [
                'customer' => $customer->customer_name,
                'phone' => $customer->mobile,
                'status' => $result['status'],
                'message' => $result['message']
            ];
        }

        return [
            'status' => 'completed',
            'message' => "Bulk send completed. Success: $success_count, Failed: $failed_count",
            'success_count' => $success_count,
            'failed_count' => $failed_count,
            'details' => $results
        ];
    }

    // Process Webhook Data
    public function process_webhook_data($data) {
        // Log incoming webhook for debugging
        log_message('info', 'WhatsApp Webhook Data: ' . json_encode($data));
        
        // Process based on webhook structure (varies by provider)
        // This is a basic implementation - customize based on your WhatsApp provider
        
        if(isset($data['messages']) && is_array($data['messages'])) {
            foreach($data['messages'] as $message) {
                // Store incoming message for customer support
                $log_data = [
                    'store_id' => get_current_store_id(),
                    'phone_number' => $message['from'] ?? '',
                    'message_type' => 'incoming',
                    'message_content' => $message['text']['body'] ?? '',
                    'status' => 'received',
                    'response_data' => json_encode($message),
                    'sent_at' => date('Y-m-d H:i:s'),
                    'created_date' => date('Y-m-d'),
                    'created_time' => date('H:i:s'),
                    'created_by' => 'Webhook',
                    'system_ip' => $this->input->ip_address(),
                    'system_name' => 'WhatsApp API'
                ];
                
                $this->db->insert($this->logs_table, $log_data);
            }
        }
    }

    // Get message statistics
    public function get_message_stats($days = 30) {
        $date_from = date('Y-m-d', strtotime("-$days days"));
        
        $this->db->select('status, COUNT(*) as count');
        $this->db->where('store_id', get_current_store_id());
        $this->db->where('created_date >=', $date_from);
        $this->db->group_by('status');
        $stats = $this->db->get($this->logs_table)->result();
        
        $result = ['sent' => 0, 'failed' => 0, 'pending' => 0];
        foreach($stats as $stat) {
            $result[$stat->status] = $stat->count;
        }
        
        return $result;
    }

    // Auto-send invoice messages
    public function auto_send_invoice_message($sales_id) {
        $store_details = get_store_details();
        
        if($store_details->whatsapp_status != 1 || $store_details->whatsapp_send_invoice != 1) {
            return false;
        }

        // Get sales details
        $this->db->select('s.*, c.customer_name, c.mobile');
        $this->db->from('db_sales s');
        $this->db->join('db_customers c', 's.customer_id = c.id');
        $this->db->where('s.id', $sales_id);
        $sales = $this->db->get()->row();

        if(!$sales || empty($sales->mobile)) {
            return false;
        }

        // Prepare variables
        $variables = [
            'CUSTOMER_NAME' => $sales->customer_name,
            'INVOICE_NO' => $sales->sales_code,
            'TOTAL_AMOUNT' => number_format($sales->grand_total, 2),
            'INVOICE_DATE' => date('d-m-Y', strtotime($sales->sales_date)),
            'DUE_DATE' => $sales->due_date ? date('d-m-Y', strtotime($sales->due_date)) : 'Immediate',
            'reference_id' => $sales_id,
            'reference_type' => 'sales'
        ];

        return $this->send_template_message($sales->customer_id, 'invoice', $variables);
    }
}
