<?php
/**
 * Bank Management Controller
 * 
 * Handles CRUD operations for bank accounts including
 * STK Push configuration and management.
 */

// Register bank management menu
register_menu("Bank Management", true, "banks_list", 'SERVICES', 'fa fa-university', '', 'info');

_admin();
$ui->assign('_title', Lang::T('Bank Management'));
$ui->assign('_system_menu', 'services');
$ui->assign('_admin', $admin);

// Check permissions
if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
    r2(U . "dashboard", 'e', Lang::T('You do not have permission to access this page'));
}

$action = $routes['1'] ?? 'list';

switch ($action) {
    case 'list':
        // List all banks
        $ui->assign('xfooter', '<script type="text/javascript" src="ui/lib/c/banks.js"></script>');
        
        // Search functionality
        $search = _post('search');
        $filter_stk = _post('filter_stk');
        $filter_active = _post('filter_active');
        
        // Alternative approach: Use direct PDO query for better performance
        $use_direct_query = true; // Set to true for direct query, false for ORM
        
        if ($use_direct_query) {
            // Direct PDO approach - faster and more reliable
            $pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_password);
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            
            $sql = "SELECT * FROM tbl_banks WHERE 1=1";
            $params = [];
            
            if (!empty($search)) {
                $sql .= " AND (name LIKE ? OR account_number LIKE ? OR account_name LIKE ?)";
                $search_term = '%' . $search . '%';
                $params[] = $search_term;
                $params[] = $search_term;
                $params[] = $search_term;
            }
            
            if ($filter_stk !== '') {
                $sql .= " AND supports_stk_push = ?";
                $params[] = $filter_stk;
            }
            
            if ($filter_active !== '') {
                $sql .= " AND is_active = ?";
                $params[] = $filter_active;
            }
            
            $sql .= " ORDER BY is_default DESC, name ASC";
            
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
            $banks = $stmt->fetchAll(PDO::FETCH_OBJ);
        } else {
            // Original ORM approach
            $query = ORM::for_table('tbl_banks');
            
            if (!empty($search)) {
                $query->where_raw('(name LIKE ? OR account_number LIKE ? OR account_name LIKE ?)', 
                    ['%' . $search . '%', '%' . $search . '%', '%' . $search . '%']);
            }
            
            if ($filter_stk !== '') {
                $query->where('supports_stk_push', $filter_stk);
            }
            
            if ($filter_active !== '') {
                $query->where('is_active', $filter_active);
            }
            
            $query->order_by_desc('is_default')->order_by_asc('name');
            $banks = Paginator::findMany($query, [
                'search' => $search,
                'filter_stk' => $filter_stk,
                'filter_active' => $filter_active
            ]);
            
            // Convert ORM object to array for template compatibility
            if ($banks && method_exists($banks, 'as_array')) {
                $banks = $banks->as_array();
            } elseif ($banks && is_object($banks)) {
                $banks_array = [];
                foreach ($banks as $bank) {
                    $banks_array[] = $bank;
                }
                $banks = $banks_array;
            }
            
            // Fallback: If banks is still not an array, use direct database query
            if (!is_array($banks) || empty($banks)) {
                $pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_password);
                $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                
                $sql = "SELECT * FROM tbl_banks WHERE 1=1";
                $params = [];
                
                if (!empty($search)) {
                    $sql .= " AND (name LIKE ? OR account_number LIKE ? OR account_name LIKE ?)";
                    $search_term = '%' . $search . '%';
                    $params[] = $search_term;
                    $params[] = $search_term;
                    $params[] = $search_term;
                }
                
                if ($filter_stk !== '') {
                    $sql .= " AND supports_stk_push = ?";
                    $params[] = $filter_stk;
                }
                
                if ($filter_active !== '') {
                    $sql .= " AND is_active = ?";
                    $params[] = $filter_active;
                }
                
                $sql .= " ORDER BY is_default DESC, name ASC";
                
                $stmt = $pdo->prepare($sql);
                $stmt->execute($params);
                $banks = $stmt->fetchAll(PDO::FETCH_OBJ);
            }
        }
        
        $ui->assign('banks', $banks);
        $ui->assign('search', $search);
        $ui->assign('filter_stk', $filter_stk);
        $ui->assign('filter_active', $filter_active);
        
        run_hook('view_list_banks');
        $ui->display('banks_basic.tpl');
        break;
        
    case 'add':
        // Show add bank form
        if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
            _alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
        }
        
        // Add JavaScript for bank add form
        $xfooter = '
        <script>
        $(document).ready(function() {
            // Form validation
            $("form").on("submit", function(e) {
                var name = $("input[name=\'name\']").val().trim();
                var accountNumber = $("input[name=\'account_number\']").val().trim();
                var accountName = $("input[name=\'account_name\']").val().trim();
                
                if (!name || !accountNumber || !accountName) {
                    e.preventDefault();
                    alert("' . Lang::T("Please fill in all required fields") . '");
                    return false;
                }
            });
            
            // Auto-generate account name from bank name
            $("input[name=\'name\']").on("blur", function() {
                var bankName = $(this).val().trim();
                if (bankName && !$("input[name=\'account_name\']").val()) {
                    $("input[name=\'account_name\']").val(bankName + " Account");
                }
            });
        });
        </script>';
        
        $ui->assign('xfooter', $xfooter);
        run_hook('view_add_bank');
        $ui->display('banks-add.tpl');
        break;
        
    case 'edit':
        // Show edit bank form
        if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
            _alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
        }
        
        $id = $routes['2'] ?? 0;
        if (!$id) {
            r2(U . 'banks/list', 'e', Lang::T('Invalid Bank ID'));
        }
        
        $bank = ORM::for_table('tbl_banks')->find_one($id);
        if (!$bank) {
            r2(U . 'banks/list', 'e', Lang::T('Bank Not Found'));
        }
        
        // Add JavaScript for bank edit form
        $xfooter = '
        <script>
        $(document).ready(function() {
            // Form validation
            $("form").on("submit", function(e) {
                var name = $("input[name=\'name\']").val().trim();
                var accountNumber = $("input[name=\'account_number\']").val().trim();
                var accountName = $("input[name=\'account_name\']").val().trim();
                
                if (!name || !accountNumber || !accountName) {
                    e.preventDefault();
                    alert("' . Lang::T("Please fill in all required fields") . '");
                    return false;
                }
            });
            
            // Warn if disabling STK Push support on default bank
            $("input[name=\'supports_stk_push\']").on("change", function() {
                if (!$(this).is(":checked") && $("input[name=\'is_default\']").is(":checked")) {
                    if (confirm("' . Lang::T("This bank is set as default. Disabling STK Push support will also remove it as default. Continue?") . '")) {
                        $("input[name=\'is_default\']").prop("checked", false);
                    } else {
                        $(this).prop("checked", true);
                    }
                }
            });
            
            // Warn if deactivating default bank
            $("input[name=\'is_active\']").on("change", function() {
                if (!$(this).is(":checked") && $("input[name=\'is_default\']").is(":checked")) {
                    if (confirm("' . Lang::T("This bank is set as default. Deactivating it will also remove it as default. Continue?") . '")) {
                        $("input[name=\'is_default\']").prop("checked", false);
                    } else {
                        $(this).prop("checked", true);
                    }
                }
            });
        });
        </script>';
        
        $ui->assign('bank', $bank);
        $ui->assign('xfooter', $xfooter);
        run_hook('view_edit_bank');
        $ui->display('banks-edit.tpl');
        break;
        
    case 'save':
        // Save bank data (add or edit)
        if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
            _alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
        }
        
        $id = _post('id');
        $name = _post('name');
        $account_number = _post('account_number');
        $account_name = _post('account_name');
        $bank_code = _post('bank_code');
        $paybill = _post('paybill');
        $supports_stk_push = _post('supports_stk_push') ? 1 : 0;
        $is_active = _post('is_active') ? 1 : 0;
        $is_default = _post('is_default') ? 1 : 0;
        
        // Validation
        $msg = '';
        if (empty($name)) {
            $msg .= Lang::T('Bank name is required') . '<br>';
        }
        if (empty($account_number)) {
            $msg .= Lang::T('Account number is required') . '<br>';
        }
        if (empty($account_name)) {
            $msg .= Lang::T('Account name is required') . '<br>';
        }
        
        // Check for duplicate account number
        $duplicate_query = ORM::for_table('tbl_banks')->where('account_number', $account_number);
        if ($id) {
            $duplicate_query->where_not_equal('id', $id);
        }
        $duplicate = $duplicate_query->find_one();
        
        if ($duplicate) {
            $msg .= Lang::T('Account number already exists') . '<br>';
        }
        
        // If setting as default, unset other defaults
        if ($is_default) {
            ORM::for_table('tbl_banks')->where('is_default', 1)->find_result_set()->set('is_default', 0)->save();
        }
        
        if ($msg) {
            $redirect_url = $id ? U . 'banks/edit/' . $id : U . 'banks/add';
            r2($redirect_url, 'e', $msg);
        }
        
        // Save bank
        if ($id) {
            $bank = ORM::for_table('tbl_banks')->find_one($id);
            if (!$bank) {
                r2(U . 'banks/list', 'e', Lang::T('Bank Not Found'));
            }
        } else {
            $bank = ORM::for_table('tbl_banks')->create();
        }
        
        $bank->name = $name;
        $bank->account_number = $account_number;
        $bank->account_name = $account_name;
        $bank->bank_code = $bank_code;
        $bank->paybill = $paybill;
        $bank->supports_stk_push = $supports_stk_push;
        $bank->is_active = $is_active;
        $bank->is_default = $is_default;
        $bank->save();
        
        $action_text = $id ? 'updated' : 'created';
        _log('[' . $admin['username'] . ']: Bank ' . $action_text . ' - ' . $name, 'Admin', $admin['id']);
        
        r2(U . 'banks/list', 's', Lang::T('Bank ' . ucfirst($action_text) . ' Successfully'));
        break;
        
    case 'delete':
        // Delete bank
        if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
            _alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
        }
        
        $id = $routes['2'] ?? 0;
        if (!$id) {
            r2(U . 'banks/list', 'e', Lang::T('Invalid Bank ID'));
        }
        
        $bank = ORM::for_table('tbl_banks')->find_one($id);
        if (!$bank) {
            r2(U . 'banks/list', 'e', Lang::T('Bank Not Found'));
        }
        
        // Check if bank is being used in appconfig
        $stk_config = ORM::for_table('tbl_appconfig')->where('setting', 'Stkbankacc')->find_one();
        if ($stk_config && $stk_config->value == $id) {
            r2(U . 'banks/list', 'e', Lang::T('Cannot delete bank that is currently selected for STK Push'));
        }
        
        $bank_name = $bank->name;
        $bank->delete();
        
        _log('[' . $admin['username'] . ']: Bank deleted - ' . $bank_name, 'Admin', $admin['id']);
        r2(U . 'banks/list', 's', Lang::T('Bank Deleted Successfully'));
        break;
        
    case 'toggle-status':
        // Toggle bank active status
        if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
            _alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
        }
        
        $id = $routes['2'] ?? 0;
        if (!$id) {
            r2(U . 'banks/list', 'e', Lang::T('Invalid Bank ID'));
        }
        
        $bank = ORM::for_table('tbl_banks')->find_one($id);
        if (!$bank) {
            r2(U . 'banks/list', 'e', Lang::T('Bank Not Found'));
        }
        
        $bank->is_active = $bank->is_active ? 0 : 1;
        $bank->save();
        
        $status_text = $bank->is_active ? 'activated' : 'deactivated';
        _log('[' . $admin['username'] . ']: Bank ' . $status_text . ' - ' . $bank->name, 'Admin', $admin['id']);
        
        r2(U . 'banks/list', 's', Lang::T('Bank ' . ucfirst($status_text) . ' Successfully'));
        break;
        
    case 'set-default':
        // Set bank as default for STK Push
        if (!in_array($admin['user_type'], ['SuperAdmin', 'Admin'])) {
            _alert(Lang::T('You do not have permission to access this page'), 'danger', "dashboard");
        }
        
        $id = $routes['2'] ?? 0;
        if (!$id) {
            r2(U . 'banks/list', 'e', Lang::T('Invalid Bank ID'));
        }
        
        $bank = ORM::for_table('tbl_banks')->find_one($id);
        if (!$bank) {
            r2(U . 'banks/list', 'e', Lang::T('Bank Not Found'));
        }
        
        if (!$bank->supports_stk_push) {
            r2(U . 'banks/list', 'e', Lang::T('Bank does not support STK Push'));
        }
        
        // Unset other defaults
        ORM::for_table('tbl_banks')->where('is_default', 1)->find_result_set()->set('is_default', 0)->save();
        
        // Set this bank as default
        $bank->is_default = 1;
        $bank->save();
        
        // Update appconfig
        $stk_config = ORM::for_table('tbl_appconfig')->where('setting', 'Stkbankacc')->find_one();
        if ($stk_config) {
            $stk_config->value = $bank->id;
            $stk_config->save();
        }
        
        $stk_name_config = ORM::for_table('tbl_appconfig')->where('setting', 'Stkbankname')->find_one();
        if ($stk_name_config) {
            $stk_name_config->value = $bank->name;
            $stk_name_config->save();
        }
        
        _log('[' . $admin['username'] . ']: Bank set as default for STK Push - ' . $bank->name, 'Admin', $admin['id']);
        r2(U . 'banks/list', 's', Lang::T('Bank Set as Default Successfully'));
        break;
        
    case 'api':
        // API endpoint for AJAX requests
        $api_action = $routes['2'] ?? '';
        
        switch ($api_action) {
            case 'get-active-banks':
                // Get banks that support STK Push and are active
                $banks = ORM::for_table('tbl_banks')
                    ->where('supports_stk_push', 1)
                    ->where('is_active', 1)
                    ->order_by_desc('is_default')
                    ->order_by_asc('name')
                    ->find_many();
                
                $result = [];
                foreach ($banks as $bank) {
                    $result[] = [
                        'id' => $bank->id,
                        'name' => $bank->name,
                        'account_number' => $bank->account_number,
                        'account_name' => $bank->account_name,
                        'is_default' => $bank->is_default
                    ];
                }
                
                header('Content-Type: application/json');
                echo json_encode($result);
                exit;
                
            case 'get-bank-details':
                // Get specific bank details
                $bank_id = $_GET['bank_id'] ?? 0;
                $bank = ORM::for_table('tbl_banks')->find_one($bank_id);
                
                if ($bank) {
                    $result = [
                        'id' => $bank->id,
                        'name' => $bank->name,
                        'account_number' => $bank->account_number,
                        'account_name' => $bank->account_name,
                        'bank_code' => $bank->bank_code,
                        'paybill' => $bank->paybill,
                        'supports_stk_push' => $bank->supports_stk_push,
                        'is_active' => $bank->is_active,
                        'is_default' => $bank->is_default
                    ];
                } else {
                    $result = ['error' => 'Bank not found'];
                }
                
                header('Content-Type: application/json');
                echo json_encode($result);
                exit;
        }
        
        r2(U . 'banks/list', 'e', Lang::T('Invalid API Action'));
        break;
        
    default:
        $ui->display('a404.tpl');
}
?>
