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

/**
 * Base Controller - All controllers should extend this
 */
class MY_Controller extends CI_Controller {

    protected $data = [];
    protected $user = null;

    public function __construct() {
        parent::__construct();
        
        // Load common models
        $this->load->model('User_model');
        $this->load->model('Notification_model');
        
        // Set base data
        $this->data['base_url'] = base_url();
        $this->data['current_url'] = current_url();
        $this->data['app_name'] = get_app_name();
    }

    /**
     * Load view with layout
     */
    protected function render($view, $data = []) {
        $data = array_merge($this->data, $data);
        $this->load->view($view, $data);
    }

    /**
     * JSON response helper
     */
    protected function json_response($data, $status_code = 200) {
        $this->output
            ->set_status_header($status_code)
            ->set_content_type('application/json')
            ->set_output(json_encode($data));
    }

    /**
     * Success JSON response
     */
    protected function success($message, $data = [], $status_code = 200) {
        $this->json_response([
            'success' => true,
            'message' => $message,
            'data' => $data
        ], $status_code);
    }

    /**
     * Error JSON response
     */
    protected function error($message, $errors = [], $status_code = 400) {
        $this->json_response([
            'success' => false,
            'message' => $message,
            'errors' => $errors
        ], $status_code);
    }

    /**
     * Format currency
     */
    protected function format_money($amount, $currency = 'USD') {
        $symbols = [
            'USD' => '$',
            'USD' => '$',
            'GBP' => '£',
            'EUR' => '€'
        ];
        
        $symbol = $symbols[$currency] ?? $currency . ' ';
        return $symbol . number_format($amount, 2);
    }

    /**
     * Log audit action
     */
    protected function log_audit($action, $entity_type = null, $entity_id = null, $old_values = null, $new_values = null) {
        $this->db->insert('audit_logs', [
            'user_id' => $this->session->userdata('user_id'),
            'action' => $action,
            'entity_type' => $entity_type,
            'entity_id' => $entity_id,
            'old_values' => $old_values ? json_encode($old_values) : null,
            'new_values' => $new_values ? json_encode($new_values) : null,
            'ip_address' => $this->input->ip_address(),
            'user_agent' => $this->input->user_agent(),
            'created_at' => date('Y-m-d H:i:s')
        ]);
    }

    /**
     * Get setting value
     */
    protected function get_setting($key, $default = null) {
        $setting = $this->db->get_where('settings', ['key' => $key])->row();
        return $setting ? $setting->value : $default;
    }
}

/**
 * Auth Controller - Requires authentication
 */
class Auth_Controller extends MY_Controller {

    public function __construct() {
        parent::__construct();
        
        // Check if user is logged in
        if (!$this->session->userdata('logged_in')) {
            if ($this->input->is_ajax_request()) {
                $this->error('Session expired. Please login again.', [], 401);
                exit;
            }
            redirect('auth/login');
        }
        
        // Get current user
        $user_id = $this->session->userdata('user_id');
        $this->user = $this->User_model->get_with_kyc($user_id);
        
        if (!$this->user) {
            $this->session->sess_destroy();
            redirect('auth/login');
        }
        
        // Check if user is active
        if ($this->user->status !== 'active') {
            $this->session->sess_destroy();
            $this->session->set_flashdata('error', 'Your account has been suspended. Please contact support.');
            redirect('auth/login');
        }
        
        // Check KYC verification status (skip for pending_activation page and logout)
        $current_route = $this->router->fetch_class() . '/' . $this->router->fetch_method();
        $allowed_routes = ['auth/pending_activation', 'auth/logout'];
        
        if (!in_array($current_route, $allowed_routes)) {
            // Get KYC status
            $kyc = $this->db->get_where('kyc', ['user_id' => $this->user->id])->row();
            
            // Redirect if KYC is pending and user is not admin
            if ($kyc && $kyc->verification_status === 'pending' && $this->user->user_type !== 'admin') {
                redirect('auth/pending_activation');
            }
        }
        
        // Set user data for views
        $this->data['user'] = $this->user;
        $this->data['unread_notifications'] = $this->Notification_model->count_unread($user_id);
    }

    /**
     * Check if user is admin
     */
    protected function is_admin() {
        return $this->user && $this->user->user_type === 'admin';
    }

    /**
     * Require admin access
     */
    protected function require_admin() {
        if (!$this->is_admin()) {
            if ($this->input->is_ajax_request()) {
                $this->error('Access denied', [], 403);
                exit;
            }
            show_error('Access denied. Admin privileges required.', 403);
        }
    }

    /**
     * Verify transaction PIN (legacy - kept for backwards compatibility)
     */
    protected function verify_pin($pin) {
        return $this->User_model->verify_pin($this->user->id, $pin);
    }
    
    /**
     * Send OTP to user's email for transaction verification
     * @param string $purpose Purpose of OTP
     * @param array $metadata Additional data to store with OTP
     * @return array Result with success status
     */
    protected function send_transaction_otp($purpose = 'transaction', $metadata = []) {
        $this->load->model('Otp_model');
        $this->load->library('mailer');
        
        // Check rate limiting
        if (!$this->Otp_model->can_request_new($this->user->id, $purpose)) {
            $remaining = $this->Otp_model->get_cooldown_remaining($this->user->id, $purpose);
            return [
                'success' => false,
                'message' => "Please wait {$remaining} seconds before requesting a new OTP.",
                'cooldown' => $remaining
            ];
        }
        
        // Generate OTP
        $otp_code = $this->Otp_model->generate($this->user->id, $purpose, $metadata);
        
        // Send OTP via email
        $full_name = trim($this->user->first_name . ' ' . $this->user->last_name) ?: $this->user->username;
        $result = $this->mailer->send_otp(
            $this->user->email,
            $full_name,
            $otp_code,
            $this->get_otp_purpose_text($purpose)
        );
        
        if ($result['success']) {
            // Mask the email for display
            $masked_email = $this->mask_email($this->user->email);
            return [
                'success' => true,
                'message' => "OTP sent to {$masked_email}",
                'masked_email' => $masked_email,
                'expires_in' => 300 // 5 minutes
            ];
        }
        
        return $result;
    }
    
    /**
     * Verify transaction OTP
     * @param string $otp_code The OTP to verify
     * @param string $purpose Purpose of OTP
     * @return array Result with success status
     */
    protected function verify_transaction_otp($otp_code, $purpose = 'transaction') {
        $this->load->model('Otp_model');
        return $this->Otp_model->verify($this->user->id, $otp_code, $purpose);
    }
    
    /**
     * Get human-readable purpose text for OTP
     */
    protected function get_otp_purpose_text($purpose) {
        $texts = [
            'transaction' => 'complete your transaction',
            'transfer' => 'confirm your transfer',
            'bank_transfer' => 'confirm your bank transfer',
            'international_transfer' => 'confirm your international transfer',
            'bill_payment' => 'confirm your bill payment',
            'card_action' => 'complete your card action',
            'profile_update' => 'update your profile',
            'password_change' => 'change your password'
        ];
        return $texts[$purpose] ?? 'complete your action';
    }
    
    /**
     * Mask email for display
     */
    protected function mask_email($email) {
        $parts = explode('@', $email);
        if (count($parts) !== 2) return $email;
        
        $name = $parts[0];
        $domain = $parts[1];
        
        if (strlen($name) <= 2) {
            $masked_name = str_repeat('*', strlen($name));
        } else {
            $masked_name = substr($name, 0, 2) . str_repeat('*', strlen($name) - 2);
        }
        
        return $masked_name . '@' . $domain;
    }
}

/**
 * Admin Controller - Requires admin privileges
 */
class Admin_Controller extends Auth_Controller {

    public function __construct() {
        parent::__construct();
        $this->require_admin();
        
        // Set admin layout flag
        $this->data['is_admin'] = true;
    }
}
