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

class Cards extends Auth_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->model('Card_model');
        $this->load->model('Account_model');
        $this->load->model('Wallet_model');
    }

    /**
     * List user cards
     */
    public function index() {
        $cards = $this->Card_model->get_by_user($this->user->id);
        $accounts = $this->Account_model->get_by_user($this->user->id);
        
        $this->data['title'] = 'My Cards';
        $this->data['cards'] = $cards;
        $this->data['accounts'] = $accounts;
        
        $this->render('cards/index', $this->data);
    }

    /**
     * View card details
     */
    public function view($id) {
        $card = $this->Card_model->get($id);
        
        if (!$card || $card->user_id != $this->user->id) {
            show_404();
            return;
        }
        
        // Get card transactions
        $transactions = $this->Card_model->get_card_transactions($id, 20);
        
        // Get linked account
        $account = $this->Account_model->get($card->account_id);
        
        $this->data['title'] = 'Card Details';
        $this->data['card'] = $card;
        $this->data['transactions'] = $transactions;
        $this->data['account'] = $account;
        
        $this->render('cards/view', $this->data);
    }

    /**
     * Create virtual card (Admin only)
     */
    public function create() {
        // Only admin can create cards
        if (!$this->is_admin()) {
            if ($this->input->is_ajax_request()) {
                $this->error('Only administrators can create cards');
                return;
            }
            $this->session->set_flashdata('error', 'Only administrators can create cards');
            redirect('cards');
            return;
        }
        
        if ($this->input->method() === 'get') {
            $accounts = $this->Account_model->get_by_user($this->user->id);
            
            $this->data['title'] = 'Create Virtual Card';
            $this->data['accounts'] = $accounts;
            
            $this->render('cards/create', $this->data);
            return;
        }
        
        $this->form_validation->set_rules('account_id', 'Account', 'required');
        
        // Only require PIN for non-admin users
        if (!$this->is_admin()) {
            $this->form_validation->set_rules('pin', 'PIN', 'required|exact_length[4]');
        }
        
        if (!$this->form_validation->run()) {
            if ($this->input->is_ajax_request()) {
                $this->error('Validation failed', validation_errors());
                return;
            }
            $this->session->set_flashdata('error', validation_errors());
            redirect('cards/create');
            return;
        }
        
        // Verify PIN only for non-admin users
        if (!$this->is_admin()) {
            if (!$this->verify_pin($this->input->post('pin'))) {
                $message = 'Invalid transaction PIN';
                if ($this->input->is_ajax_request()) {
                    $this->error($message);
                    return;
                }
                $this->session->set_flashdata('error', $message);
                redirect('cards/create');
                return;
            }
        }
        
        // Verify account belongs to user
        $account = $this->Account_model->get($this->input->post('account_id'));
        if (!$account || $account->user_id != $this->user->id) {
            $message = 'Invalid account';
            if ($this->input->is_ajax_request()) {
                $this->error($message);
                return;
            }
            $this->session->set_flashdata('error', $message);
            redirect('cards/create');
            return;
        }
        
        $result = $this->Card_model->create_virtual_card(
            $this->user->id,
            $account->id,
            $this->input->post('currency', TRUE) ?: 'USD'
        );
        
        if ($result['success']) {
            // Store card details temporarily in session for display
            $this->session->set_flashdata('new_card_details', $result['card_details']);
            
            if ($this->input->is_ajax_request()) {
                $this->success($result['message'], [
                    'card_id' => $result['card_id'],
                    'card_details' => $result['card_details']
                ]);
                return;
            }
            
            $this->session->set_flashdata('success', $result['message']);
            redirect('cards/view/' . $result['card_id']);
        } else {
            if ($this->input->is_ajax_request()) {
                $this->error($result['message']);
                return;
            }
            $this->session->set_flashdata('error', $result['message']);
            redirect('cards/create');
        }
    }

    /**
     * Activate card
     */
    public function activate($id) {
        $card = $this->Card_model->get($id);
        
        if (!$card || $card->user_id != $this->user->id) {
            $this->error('Card not found');
            return;
        }
        
        if ($card->status === 'active') {
            $this->error('Card is already active');
            return;
        }
        
        $this->Card_model->activate($id);
        $this->success('Card activated successfully');
    }

    /**
     * Freeze card
     */
    public function freeze($id) {
        $card = $this->Card_model->get($id);
        
        if (!$card || $card->user_id != $this->user->id) {
            $this->error('Card not found');
            return;
        }
        
        $reason = $this->input->post('reason', TRUE);
        $this->Card_model->freeze($id, $reason);
        
        $this->Notification_model->send_security_notification($this->user->id, 'card_frozen', [
            'card' => $card->card_number_masked
        ]);
        
        $this->success('Card frozen successfully');
    }

    /**
     * Unfreeze card
     */
    public function unfreeze($id) {
        $card = $this->Card_model->get($id);
        
        if (!$card || $card->user_id != $this->user->id) {
            $this->error('Card not found');
            return;
        }
        
        // Verify PIN only for non-admin users
        if (!$this->is_admin()) {
            if (!$this->verify_pin($this->input->post('pin'))) {
                $this->error('Invalid transaction PIN');
                return;
            }
        }
        
        $this->Card_model->unfreeze($id);
        $this->success('Card unfrozen successfully');
    }

    /**
     * Fund card
     */
    public function fund($id) {
        $card = $this->Card_model->get($id);
        
        if (!$card || $card->user_id != $this->user->id) {
            if ($this->input->is_ajax_request()) {
                $this->error('Card not found');
                return;
            }
            show_404();
            return;
        }
        
        if ($this->input->method() === 'get') {
            $accounts = $this->Account_model->get_by_user($this->user->id);
            
            $this->data['title'] = 'Fund Card';
            $this->data['card'] = $card;
            $this->data['accounts'] = $accounts;
            
            $this->render('cards/fund', $this->data);
            return;
        }
        
        $this->form_validation->set_rules('account_id', 'Source Account', 'required');
        $this->form_validation->set_rules('amount', 'Amount', 'required|numeric|greater_than[0]');
        
        // Only require PIN for non-admin users
        if (!$this->is_admin()) {
            $this->form_validation->set_rules('pin', 'PIN', 'required|exact_length[4]');
        }
        
        if (!$this->form_validation->run()) {
            if ($this->input->is_ajax_request()) {
                $this->error('Validation failed', validation_errors());
                return;
            }
            $this->session->set_flashdata('error', validation_errors());
            redirect('cards/fund/' . $id);
            return;
        }
        
        // Verify PIN only for non-admin users
        if (!$this->is_admin()) {
            if (!$this->verify_pin($this->input->post('pin'))) {
                $message = 'Invalid transaction PIN';
                if ($this->input->is_ajax_request()) {
                    $this->error($message);
                    return;
                }
                $this->session->set_flashdata('error', $message);
                redirect('cards/fund/' . $id);
                return;
            }
        }
        
        // Verify account
        $account = $this->Account_model->get($this->input->post('account_id'));
        if (!$account || $account->user_id != $this->user->id) {
            $message = 'Invalid account';
            if ($this->input->is_ajax_request()) {
                $this->error($message);
                return;
            }
            $this->session->set_flashdata('error', $message);
            redirect('cards/fund/' . $id);
            return;
        }
        
        $wallet = $this->Wallet_model->get_by_account($account->id, $account->currency);
        $amount = floatval($this->input->post('amount'));
        
        $result = $this->Card_model->fund($id, $amount, $wallet->id);
        
        if ($result['success']) {
            $this->Notification_model->send_transaction_notification(
                $this->user->id, 'card_funding', $amount, 'Card funding'
            );
            
            if ($this->input->is_ajax_request()) {
                $this->success($result['message'], ['new_balance' => $result['new_balance']]);
                return;
            }
            $this->session->set_flashdata('success', $result['message']);
            redirect('cards/view/' . $id);
        } else {
            if ($this->input->is_ajax_request()) {
                $this->error($result['message']);
                return;
            }
            $this->session->set_flashdata('error', $result['message']);
            redirect('cards/fund/' . $id);
        }
    }

    /**
     * Withdraw from card
     */
    public function withdraw($id) {
        $card = $this->Card_model->get($id);
        
        if (!$card || $card->user_id != $this->user->id) {
            if ($this->input->is_ajax_request()) {
                $this->error('Card not found');
                return;
            }
            show_404();
            return;
        }
        
        if ($this->input->method() === 'get') {
            $accounts = $this->Account_model->get_by_user($this->user->id);
            
            $this->data['title'] = 'Withdraw from Card';
            $this->data['card'] = $card;
            $this->data['accounts'] = $accounts;
            
            $this->render('cards/withdraw', $this->data);
            return;
        }
        
        $this->form_validation->set_rules('account_id', 'Destination Account', 'required');
        $this->form_validation->set_rules('amount', 'Amount', 'required|numeric|greater_than[0]');
        
        // Only require PIN for non-admin users
        if (!$this->is_admin()) {
            $this->form_validation->set_rules('pin', 'PIN', 'required|exact_length[4]');
        }
        
        if (!$this->form_validation->run()) {
            if ($this->input->is_ajax_request()) {
                $this->error('Validation failed', validation_errors());
                return;
            }
            $this->session->set_flashdata('error', validation_errors());
            redirect('cards/withdraw/' . $id);
            return;
        }
        
        // Verify PIN only for non-admin users
        if (!$this->is_admin()) {
            if (!$this->verify_pin($this->input->post('pin'))) {
                $message = 'Invalid transaction PIN';
                if ($this->input->is_ajax_request()) {
                    $this->error($message);
                    return;
                }
                $this->session->set_flashdata('error', $message);
                redirect('cards/withdraw/' . $id);
                return;
            }
        }
        
        // Verify account
        $account = $this->Account_model->get($this->input->post('account_id'));
        if (!$account || $account->user_id != $this->user->id) {
            $message = 'Invalid account';
            if ($this->input->is_ajax_request()) {
                $this->error($message);
                return;
            }
            $this->session->set_flashdata('error', $message);
            redirect('cards/withdraw/' . $id);
            return;
        }
        
        $wallet = $this->Wallet_model->get_by_account($account->id, $account->currency);
        $amount = floatval($this->input->post('amount'));
        
        $result = $this->Card_model->withdraw($id, $amount, $wallet->id);
        
        if ($result['success']) {
            if ($this->input->is_ajax_request()) {
                $this->success($result['message'], ['new_balance' => $result['new_balance']]);
                return;
            }
            $this->session->set_flashdata('success', $result['message']);
            redirect('cards/view/' . $id);
        } else {
            if ($this->input->is_ajax_request()) {
                $this->error($result['message']);
                return;
            }
            $this->session->set_flashdata('error', $result['message']);
            redirect('cards/withdraw/' . $id);
        }
    }

    /**
     * Update card controls
     */
    public function controls($id) {
        $card = $this->Card_model->get($id);
        
        if (!$card || $card->user_id != $this->user->id) {
            $this->error('Card not found');
            return;
        }
        
        $this->Card_model->update_controls($id, [
            'is_online_enabled' => $this->input->post('is_online_enabled') ? 1 : 0,
            'is_pos_enabled' => $this->input->post('is_pos_enabled') ? 1 : 0,
            'is_atm_enabled' => $this->input->post('is_atm_enabled') ? 1 : 0,
            'is_international_enabled' => $this->input->post('is_international_enabled') ? 1 : 0
        ]);
        
        $this->success('Card controls updated');
    }

    /**
     * Update card limits
     */
    public function limits($id) {
        $card = $this->Card_model->get($id);
        
        if (!$card || $card->user_id != $this->user->id) {
            $this->error('Card not found');
            return;
        }
        
        $this->Card_model->update_limits($id, [
            'daily_limit' => floatval($this->input->post('daily_limit')),
            'monthly_limit' => floatval($this->input->post('monthly_limit')),
            'single_transaction_limit' => floatval($this->input->post('single_transaction_limit'))
        ]);
        
        $this->success('Card limits updated');
    }

    /**
     * Card transactions
     */
    public function transactions($id) {
        $card = $this->Card_model->get($id);
        
        if (!$card || $card->user_id != $this->user->id) {
            show_404();
            return;
        }
        
        $transactions = $this->Card_model->get_card_transactions($id, 50);
        
        $this->data['title'] = 'Card Transactions';
        $this->data['card'] = $card;
        $this->data['transactions'] = $transactions;
        
        $this->render('cards/transactions', $this->data);
    }
}
