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

if (!function_exists('get_base_currency')) {
    /**
     * Get the base currency for the store
     */
    function get_base_currency($store_id = null) {
        $CI =& get_instance();
        
        if ($store_id === null) {
            $store_id = get_current_store_id();
        }
        
        $CI->db->select('c.*');
        $CI->db->from('db_currency c');
        $CI->db->join('db_store s', 's.currency_id = c.id');
        $CI->db->where('s.id', $store_id);
        $CI->db->where('c.status', 1);
        
        $query = $CI->db->get();
        return $query->row();
    }
}

if (!function_exists('get_base_currency_symbol')) {
    /**
     * Get the base currency symbol for the store
     */
    function get_base_currency_symbol($store_id = null) {
        $base_currency = get_base_currency($store_id);
        return $base_currency ? $base_currency->symbol : '$';
    }
}

if (!function_exists('get_base_currency_id')) {
    /**
     * Get the base currency ID for the store
     */
    function get_base_currency_id($store_id = null) {
        $base_currency = get_base_currency($store_id);
        return $base_currency ? $base_currency->id : 1;
    }
}


if (!function_exists('get_exchange_rate')) {
    /**
     * Get exchange rate between two currencies
     */
    function get_exchange_rate($from_currency_id, $to_currency_id, $store_id = null, $date = null) {
        $CI =& get_instance();
        
        if ($store_id === null) {
            $store_id = get_current_store_id();
        }
        
        if ($date === null) {
            $date = date('Y-m-d');
        }
        
        // If same currency, return 1
        if ($from_currency_id == $to_currency_id) {
            return 1.000000;
        }
        
        $CI->db->select('exchange_rate');
        $CI->db->from('db_exchange_rates');
        $CI->db->where('from_currency_id', $from_currency_id);
        $CI->db->where('to_currency_id', $to_currency_id);
        $CI->db->where('effective_date <=', $date);
        $CI->db->where('status', 1);
        // Remove rate_type filter to include both manual and API rates
        $CI->db->order_by('effective_date', 'DESC');
        $CI->db->limit(1);
        
        $query = $CI->db->get();
        if ($query->num_rows() > 0) {
            return $query->row()->exchange_rate;
        }
        
        // If no direct rate found, try reverse rate
        $CI->db->select('exchange_rate');
        $CI->db->from('db_exchange_rates');
        $CI->db->where('from_currency_id', $to_currency_id);
        $CI->db->where('to_currency_id', $from_currency_id);
        $CI->db->where('effective_date <=', $date);
        $CI->db->where('status', 1);
        // Remove rate_type filter to include both manual and API rates
        $CI->db->order_by('effective_date', 'DESC');
        $CI->db->limit(1);
        
        $query = $CI->db->get();
        if ($query->num_rows() > 0) {
            return 1 / $query->row()->exchange_rate;
        }
        
        // If still no rate found, log the issue and return false
        log_message('error', "No exchange rate found for {$from_currency_id} to {$to_currency_id} on {$date}");
        return false;
    }
}

if (!function_exists('convert_currency')) {
    /**
     * Convert amount from one currency to another
     */
    function convert_currency($amount, $from_currency_id, $to_currency_id, $store_id = null, $date = null) {
        // If same currency, return same amount
        if ($from_currency_id == $to_currency_id) {
            return $amount;
        }
        
        $exchange_rate = get_exchange_rate($from_currency_id, $to_currency_id, $store_id, $date);
        if ($exchange_rate === false) {
            return false; // No exchange rate available
        }
        return $amount * $exchange_rate;
    }
    
    function get_currency_name($currency_id, $store_id = null) {
        $CI =& get_instance();
        
        if ($store_id === null) {
            $store_id = get_current_store_id();
        }
        
        $CI->db->select('currency_name');
        $CI->db->from('db_currency');
        $CI->db->where('id', $currency_id);
        $CI->db->where('status', 1);
        $query = $CI->db->get();
        
        if ($query->num_rows() > 0) {
            return $query->row()->currency_name;
        }
        
        return 'Unknown Currency';
    }
}

if (!function_exists('format_currency_amount')) {
    /**
     * Format currency amount with proper symbol and decimal places
     */
    function format_currency_amount($amount, $currency_id = null, $store_id = null) {
        $CI =& get_instance();
        
        if ($currency_id === null) {
            $currency = get_base_currency($store_id);
        } else {
            $CI->db->select('*');
            $CI->db->from('db_currency');
            $CI->db->where('id', $currency_id);
            $CI->db->where('status', 1);
            $query = $CI->db->get();
            $currency = $query->row();
        }
        
        if (!$currency) {
            return number_format($amount, 2);
        }
        
        $decimal_places = isset($currency->decimal_places) ? $currency->decimal_places : 2;
        $symbol = isset($currency->currency_symbol) ? $currency->currency_symbol : $currency->symbol;
        $position = isset($currency->currency_position) ? $currency->currency_position : 'before';
        
        // Handle negative amounts correctly
        $is_negative = $amount < 0;
        $absolute_amount = abs($amount);
        $formatted_amount = number_format($absolute_amount, $decimal_places);
        
        if ($position == 'before') {
            return ($is_negative ? '-' : '') . $symbol . ' ' . $formatted_amount;
        } else {
            return ($is_negative ? '-' : '') . $formatted_amount . ' ' . $symbol;
        }
    }
}

if (!function_exists('format_currency_with_system')) {
    /**
     * Format currency amount in account currency with system currency in parentheses
     * Format: 80,000 ( $25 ) - account currency amount with system currency in parentheses
     */
    function format_currency_with_system($amount, $account_currency_id, $system_currency_id = null, $store_id = null) {
        $CI =& get_instance();
        
        if ($system_currency_id === null) {
            $system_currency = get_base_currency($store_id);
            $system_currency_id = $system_currency->id;
        }
        
        // Get account currency info
        $account_currency = $CI->db->select('*')
            ->from('db_currency')
            ->where('id', $account_currency_id)
            ->where('status', 1)
            ->get()->row();
            
        // Get system currency info
        $system_currency = $CI->db->select('*')
            ->from('db_currency')
            ->where('id', $system_currency_id)
            ->where('status', 1)
            ->get()->row();
        
        if (!$account_currency || !$system_currency) {
            return number_format($amount, 2);
        }
        
        // Format account currency amount
        $account_decimal_places = isset($account_currency->decimal_places) ? $account_currency->decimal_places : 2;
        $account_symbol = isset($account_currency->currency_symbol) ? $account_currency->currency_symbol : $account_currency->symbol;
        $account_position = isset($account_currency->currency_position) ? $account_currency->currency_position : 'before';
        
        // Handle negative amounts correctly
        $is_negative = $amount < 0;
        $absolute_amount = abs($amount);
        $formatted_account_amount = number_format($absolute_amount, $account_decimal_places);
        
        if ($account_position == 'before') {
            $account_display = ($is_negative ? '-' : '') . $account_symbol . ' ' . $formatted_account_amount;
        } else {
            $account_display = ($is_negative ? '-' : '') . $formatted_account_amount . ' ' . $account_symbol;
        }
        
        // Convert to system currency if different
        if ($account_currency_id != $system_currency_id) {
            $system_amount = convert_currency($amount, $account_currency_id, $system_currency_id);
            $system_decimal_places = isset($system_currency->decimal_places) ? $system_currency->decimal_places : 2;
            $system_symbol = isset($system_currency->currency_symbol) ? $system_currency->currency_symbol : $system_currency->symbol;
            $system_position = isset($system_currency->currency_position) ? $system_currency->currency_position : 'before';
            
            // Handle negative amounts for system currency
            $system_is_negative = $system_amount < 0;
            $system_absolute_amount = abs($system_amount);
            $formatted_system_amount = number_format($system_absolute_amount, $system_decimal_places);
            
            if ($system_position == 'before') {
                $system_display = ($system_is_negative ? '-' : '') . $system_symbol . ' ' . $formatted_system_amount;
            } else {
                $system_display = ($system_is_negative ? '-' : '') . $formatted_system_amount . ' ' . $system_symbol;
            }
            
            return $account_display . ' ( ' . $system_display . ' )';
        } else {
            return $account_display;
        }
    }
}

if (!function_exists('format_system_with_account')) {
    /**
     * Format currency amount with system currency first and account currency in parentheses
     * Format: $25 ( USh 25.45 ) - system currency amount with account currency in parentheses
     */
    function format_system_with_account($amount, $account_currency_id, $system_currency_id = null, $store_id = null) {
        $CI =& get_instance();
        
        if ($system_currency_id === null) {
            $system_currency = get_base_currency($store_id);
            $system_currency_id = $system_currency->id;
        }
        
        // Get account currency info
        $account_currency = $CI->db->select('*')
            ->from('db_currency')
            ->where('id', $account_currency_id)
            ->where('status', 1)
            ->get()->row();
            
        // Get system currency info
        $system_currency = $CI->db->select('*')
            ->from('db_currency')
            ->where('id', $system_currency_id)
            ->where('status', 1)
            ->get()->row();
        
        if (!$account_currency || !$system_currency) {
            return number_format($amount, 2);
        }
        
        // Convert amount to system currency if different
        if ($account_currency_id != $system_currency_id) {
            $system_amount = convert_currency($amount, $account_currency_id, $system_currency_id);
        } else {
            $system_amount = $amount;
        }
        
        // Format system currency amount
        $system_decimal_places = isset($system_currency->decimal_places) ? $system_currency->decimal_places : 2;
        $system_symbol = isset($system_currency->currency_symbol) ? $system_currency->currency_symbol : $system_currency->symbol;
        $system_position = isset($system_currency->currency_position) ? $system_currency->currency_position : 'before';
        
        // Handle negative amounts for system currency
        $system_is_negative = $system_amount < 0;
        $system_absolute_amount = abs($system_amount);
        $formatted_system_amount = number_format($system_absolute_amount, $system_decimal_places);
        
        if ($system_position == 'before') {
            $system_display = ($system_is_negative ? '-' : '') . $system_symbol . ' ' . $formatted_system_amount;
        } else {
            $system_display = ($system_is_negative ? '-' : '') . $formatted_system_amount . ' ' . $system_symbol;
        }
        
        // Format account currency amount
        $account_decimal_places = isset($account_currency->decimal_places) ? $account_currency->decimal_places : 2;
        $account_symbol = isset($account_currency->currency_symbol) ? $account_currency->currency_symbol : $account_currency->symbol;
        $account_position = isset($account_currency->currency_position) ? $account_currency->currency_position : 'before';
        
        // Handle negative amounts for account currency
        $account_is_negative = $amount < 0;
        $account_absolute_amount = abs($amount);
        $formatted_account_amount = number_format($account_absolute_amount, $account_decimal_places);
        
        if ($account_position == 'before') {
            $account_display = ($account_is_negative ? '-' : '') . $account_symbol . ' ' . $formatted_account_amount;
        } else {
            $account_display = ($account_is_negative ? '-' : '') . $formatted_account_amount . ' ' . $account_symbol;
        }
        
        // Return system currency first with account currency in parentheses
        if ($account_currency_id != $system_currency_id) {
            return $system_display . ' ( ' . $account_display . ' )';
        } else {
            return $system_display;
        }
    }
}

if (!function_exists('get_currency_list')) {
    /**
     * Get list of active currencies
     */
    function get_currency_list($store_id = null) {
        $CI =& get_instance();
        
        if ($store_id === null) {
            $store_id = get_current_store_id();
        }
        
        $CI->db->select('*');
        $CI->db->from('db_currency');
        $CI->db->where('status', 1);
        $CI->db->order_by('is_base_currency', 'DESC');
        $CI->db->order_by('currency_name', 'ASC');
        
        $query = $CI->db->get();
        return $query->result();
    }
}

if (!function_exists('get_customer_trading_currency')) {
    /**
     * Get customer's trading currency or default to base currency
     */
    function get_customer_trading_currency($customer_id, $store_id = null) {
        $CI =& get_instance();
        
        if ($store_id === null) {
            $store_id = get_current_store_id();
        }
        
        // Get currency from customer's trading_currency_id column
        $CI->db->select('c.trading_currency_id, c.currency_exchange_rate, curr.*');
        $CI->db->from('db_customers c');
        $CI->db->join('db_currency curr', 'curr.id = c.trading_currency_id', 'left');
        $CI->db->where('c.id', $customer_id);
        $CI->db->where('c.store_id', $store_id);
        
        $query = $CI->db->get();
        $result = $query->row();
        
        if ($result && $result->trading_currency_id) {
            return $result;
        }
        
        // If no result found with the store_id, try without store_id filter
        $CI->db->select('c.trading_currency_id, c.currency_exchange_rate, curr.*');
        $CI->db->from('db_customers c');
        $CI->db->join('db_currency curr', 'curr.id = c.trading_currency_id', 'left');
        $CI->db->where('c.id', $customer_id);
        
        $query = $CI->db->get();
        $result = $query->row();
        
        if ($result && $result->trading_currency_id) {
            return $result;
        }
        
        // Return base currency as fallback
        return get_base_currency($store_id);
    }
}

if (!function_exists('get_supplier_trading_currency')) {
    /**
     * Get supplier's trading currency or default to base currency
     */
    function get_supplier_trading_currency($supplier_id, $store_id = null) {
        $CI =& get_instance();
        
        if ($store_id === null) {
            $store_id = get_current_store_id();
        }
        
        $CI->db->select('s.trading_currency_id, s.currency_exchange_rate, curr.*');
        $CI->db->from('db_suppliers s');
        $CI->db->join('db_currency curr', 'curr.id = s.trading_currency_id', 'left');
        $CI->db->where('s.id', $supplier_id);
        $CI->db->where('s.store_id', $store_id);
        
        $query = $CI->db->get();
        $result = $query->row();
        
        if ($result && $result->trading_currency_id) {
            return $result;
        }
        
        // Return base currency if no trading currency set
        return get_base_currency($store_id);
    }
}

if (!function_exists('log_currency_conversion')) {
    /**
     * Log currency conversion for audit purposes
     */
    function log_currency_conversion($transaction_type, $transaction_id, $from_currency_id, $to_currency_id, $original_amount, $converted_amount, $exchange_rate, $created_by = null) {
        $CI =& get_instance();
        
        if ($created_by === null) {
            $created_by = get_current_user_id();
        }
        
        $data = array(
            'store_id' => get_current_store_id(),
            'transaction_type' => $transaction_type,
            'transaction_id' => $transaction_id,
            'from_currency_id' => $from_currency_id,
            'to_currency_id' => $to_currency_id,
            'original_amount' => $original_amount,
            'converted_amount' => $converted_amount,
            'exchange_rate' => $exchange_rate,
            'created_by' => $created_by
        );
        
        $CI->db->insert('db_currency_conversion_log', $data);
    }
}

if (!function_exists('get_current_store_id')) {
    /**
     * Get current store ID from session
     */
    function get_current_store_id() {
        $CI =& get_instance();
        return $CI->session->userdata('store_id') ?: 1;
    }
}

if (!function_exists('get_current_user_id')) {
    /**
     * Get current user ID from session
     */
    function get_current_user_id() {
        $CI =& get_instance();
        return $CI->session->userdata('user_id') ?: 'system';
    }
}

if (!function_exists('update_exchange_rate')) {
    /**
     * Update or create exchange rate
     */
    function update_exchange_rate($from_currency_id, $to_currency_id, $exchange_rate, $store_id = null, $effective_date = null, $created_by = null) {
        $CI =& get_instance();
        
        if ($store_id === null) {
            $store_id = get_current_store_id();
        }
        
        if ($effective_date === null) {
            $effective_date = date('Y-m-d');
        }
        
        if ($created_by === null) {
            $created_by = get_current_user_id();
        }
        
        // Check if rate already exists for this date
        $CI->db->select('id');
        $CI->db->from('db_exchange_rates');
        $CI->db->where('from_currency_id', $from_currency_id);
        $CI->db->where('to_currency_id', $to_currency_id);
        $CI->db->where('effective_date', $effective_date);
        
        $query = $CI->db->get();
        
        $data = array(
            'from_currency_id' => $from_currency_id,
            'to_currency_id' => $to_currency_id,
            'exchange_rate' => $exchange_rate,
            'rate_type' => 'manual',
            'effective_date' => $effective_date,
            'status' => 1,
            'created_by' => $created_by,
            'system_ip' => $_SERVER['REMOTE_ADDR'] ?? '',
            'system_name' => $_SERVER['HTTP_USER_AGENT'] ?? ''
        );
        
        if ($query->num_rows() > 0) {
            // Update existing rate
            $CI->db->where('id', $query->row()->id);
            $CI->db->update('db_exchange_rates', $data);
        } else {
            // Insert new rate
            $CI->db->insert('db_exchange_rates', $data);
        }
        
        return $CI->db->affected_rows() > 0;
    }
}

if (!function_exists('get_currency_by_id')) {
    /**
     * Get currency details by ID
     */
    function get_currency_by_id($currency_id) {
        $CI =& get_instance();
        
        $CI->db->select('*');
        $CI->db->from('db_currency');
        $CI->db->where('id', $currency_id);
        $CI->db->where('status', 1);
        
        $query = $CI->db->get();
        return $query->row();
    }
}

if (!function_exists('get_store_currency')) {
    /**
     * Get the currency set in store settings
     */
    function get_store_currency($store_id = null) {
        $CI =& get_instance();
        
        if ($store_id === null) {
            $store_id = get_current_store_id();
        }
        
        $CI->db->select('c.*');
        $CI->db->from('db_currency c');
        $CI->db->join('db_store s', 's.currency_id = c.id');
        $CI->db->where('s.id', $store_id);
        $CI->db->where('c.status', 1);
        
        $query = $CI->db->get();
        return $query->row();
    }
}
