<?php

namespace App\Controllers;
use App\Models\TransactionModel;
use CodeIgniter\Controller;

class AdminController extends Controller
{
    public function __construct()
    {
        helper(['url']);
    }

    /** True if client wants JSON (app / AJAX). */
    private function wantsJson(): bool
    {
        $accept = $this->request->getHeaderLine('Accept');
        $with = $this->request->getHeaderLine('X-Requested-With');
        return (strpos($accept, 'application/json') !== false) || ($with === 'XMLHttpRequest');
    }

    /**
     * YEM recorded transactions: filter params from GET (admin/yem) or POST (refresh redirect).
     *
     * @return array{start_date:?string,end_date:?string,uid:string,reason:string,hash:string,status:?string,asset:string,value_min:?string,value_max:?string}
     */
    private function getYemFilterParamsFromRequest(bool $fromPost = false): array
    {
        $req = $fromPost ? $this->request->getPost() : $this->request->getGet();

        return [
            'start_date' => isset($req['start_date']) && $req['start_date'] !== '' ? (string) $req['start_date'] : null,
            'end_date'   => isset($req['end_date']) && $req['end_date'] !== '' ? (string) $req['end_date'] : null,
            'uid'        => isset($req['uid']) ? trim((string) $req['uid']) : '',
            'reason'     => isset($req['reason']) ? trim((string) $req['reason']) : '',
            'hash'       => isset($req['hash']) ? trim((string) $req['hash']) : '',
            'status'     => isset($req['status']) && $req['status'] !== '' ? (string) $req['status'] : null,
            'asset'      => isset($req['asset']) ? trim((string) $req['asset']) : '',
            'value_min'  => isset($req['value_min']) && $req['value_min'] !== '' ? (string) $req['value_min'] : null,
            'value_max'  => isset($req['value_max']) && $req['value_max'] !== '' ? (string) $req['value_max'] : null,
        ];
    }

    /**
     * Apply YEM transaction list filters to the model (before orderBy / paginate).
     */
    private function applyYemTransactionFilters(\App\Models\YemTransactionModel $model, array $f): void
    {
        if (! empty($f['start_date']) && ! empty($f['end_date'])) {
            $model->where('created_at >=', $f['start_date'] . ' 00:00:00')
                ->where('created_at <=', $f['end_date'] . ' 23:59:59');
        } elseif (! empty($f['start_date'])) {
            $model->where('created_at >=', $f['start_date'] . ' 00:00:00');
        } elseif (! empty($f['end_date'])) {
            $model->where('created_at <=', $f['end_date'] . ' 23:59:59');
        }

        if ($f['uid'] !== '') {
            $model->groupStart()
                ->like('from_uid', $f['uid'], 'both')
                ->orLike('to_uid', $f['uid'], 'both')
                ->groupEnd();
        }

        if ($f['reason'] !== '') {
            $model->like('reason', $f['reason'], 'both');
        }

        if ($f['hash'] !== '') {
            $model->like('hash', $f['hash'], 'both');
        }

        if (! empty($f['status']) && $f['status'] !== 'all') {
            $model->where('status', $f['status']);
        }

        if ($f['asset'] !== '') {
            $model->like('asset', $f['asset'], 'both');
        }

        if ($f['value_min'] !== null && is_numeric($f['value_min'])) {
            $model->where('value >=', (float) $f['value_min']);
        }

        if ($f['value_max'] !== null && is_numeric($f['value_max'])) {
            $model->where('value <=', (float) $f['value_max']);
        }
    }

    /** True if any YEM list filter is active (for empty-state messaging). */
    private function yemFiltersActive(array $f): bool
    {
        if (! empty($f['start_date']) || ! empty($f['end_date'])) {
            return true;
        }
        if ($f['uid'] !== '' || $f['reason'] !== '' || $f['hash'] !== '' || $f['asset'] !== '') {
            return true;
        }
        if (! empty($f['status']) && $f['status'] !== 'all') {
            return true;
        }
        if ($f['value_min'] !== null || $f['value_max'] !== null) {
            return true;
        }

        return false;
    }

    public function login()
    {
        return view('admin/login');
    }

    public function auth()
    {
        // Support both form (web) and JSON (app)
        $username = $this->request->getPost('username');
        $password = $this->request->getPost('password');
        if ($username === null || $username === '') {
            $json = $this->request->getJSON(true);
            if (is_array($json)) {
                $username = $json['username'] ?? '';
                $password = $json['password'] ?? '';
            }
        }

        $adminUsername = env('admin.username', 'admin');
        $adminPassword = env('admin.password', 'admin123');

        $wantsJson = (strpos($this->request->getHeaderLine('Accept'), 'application/json') !== false)
            || $this->request->getHeaderLine('X-Requested-With') === 'XMLHttpRequest';

        if ($username === $adminUsername && $password === $adminPassword) {
            session()->set('isLoggedIn', true);
            session()->set('admin_username', $username);

            if ($wantsJson) {
                return $this->response->setJSON(['success' => true, 'username' => $username]);
            }
            header('Location: ' . site_url('admin/dashboard'));
            exit();
        }

        if ($wantsJson) {
            return $this->response->setJSON(['success' => false, 'error' => 'Invalid credentials'])->setStatusCode(401);
        }
        session()->setFlashdata('error', 'Invalid credentials');
        header('Location: ' . site_url('admin/login'));
        exit();
    }

    public function dashboard()
    {
        if (!session()->get('isLoggedIn')) {
            if ($this->wantsJson()) {
                return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
            }
            return redirect()->to(site_url('admin/login'));
        }

        $transactionModel = new TransactionModel();
        $paymentTransactionModel = new \App\Models\PaymentTransactionModel();
        
        // Get all transactions for calculations (original transactions)
        $allTransactions = $transactionModel->findAll();
        
        // Get all Relworx transactions for calculations
        $allRelworxTransactions = $paymentTransactionModel->findAll();
        
        // Initialize counters and amounts for original transactions
        $successfulCount = 0;
        $failedCount = 0;
        $pendingCount = 0;
        $successfulAmount = 0;
        $failedAmount = 0;
        $pendingAmount = 0;
        
        // Calculate counts and amounts for original transactions
        foreach ($allTransactions as $transaction) {
            $status = strtoupper($transaction['status']);
            $amount = (float) $transaction['amount'];
            
            switch ($status) {
                case 'SUCCESS':
                    $successfulCount++;
                    $successfulAmount += $amount;
                    break;
                case 'FAILED':
                    $failedCount++;
                    $failedAmount += $amount;
                    break;
                case 'PENDING':
                    $pendingCount++;
                    $pendingAmount += $amount;
                    break;
            }
        }
        
        // Initialize counters and amounts for Relworx transactions
        $relworxSuccessfulCount = 0;
        $relworxFailedCount = 0;
        $relworxPendingCount = 0;
        $relworxSuccessfulAmount = 0;
        $relworxFailedAmount = 0;
        $relworxPendingAmount = 0;
        
        // Calculate counts and amounts for Relworx transactions
        foreach ($allRelworxTransactions as $transaction) {
            $status = strtoupper($transaction['status']);
            $amount = (float) $transaction['amount'];
            
            switch ($status) {
                case 'SUCCESS':
                    $relworxSuccessfulCount++;
                    $relworxSuccessfulAmount += $amount;
                    break;
                case 'FAILED':
                    $relworxFailedCount++;
                    $relworxFailedAmount += $amount;
                    break;
                case 'PENDING':
                    $relworxPendingCount++;
                    $relworxPendingAmount += $amount;
                    break;
            }
        }
        
        // Calculate transaction type breakdown for Relworx
        $relworxPayments = $paymentTransactionModel->where('payment_method', 'mobile_money')->findAll();
        $relworxSends = $paymentTransactionModel->where('payment_method', 'mobile_money_send')->findAll();
        $relworxProducts = $paymentTransactionModel->where('payment_method', 'product_purchase')->findAll();
        $relworxVisa = $paymentTransactionModel->where('payment_method', 'visa_mastercard')->findAll();
        
        $data = [
            // Original transaction stats
            'successful_count' => $successfulCount,
            'failed_count' => $failedCount,
            'pending_count' => $pendingCount,
            'successful_amount' => $successfulAmount,
            'failed_amount' => $failedAmount,
            'pending_amount' => $pendingAmount,
            'total_count' => $successfulCount + $failedCount + $pendingCount,
            'total_amount' => $successfulAmount + $failedAmount + $pendingAmount,
            
            // Relworx transaction stats
            'relworx_successful_count' => $relworxSuccessfulCount,
            'relworx_failed_count' => $relworxFailedCount,
            'relworx_pending_count' => $relworxPendingCount,
            'relworx_successful_amount' => $relworxSuccessfulAmount,
            'relworx_failed_amount' => $relworxFailedAmount,
            'relworx_pending_amount' => $relworxPendingAmount,
            'relworx_total_count' => $relworxSuccessfulCount + $relworxFailedCount + $relworxPendingCount,
            'relworx_total_amount' => $relworxSuccessfulAmount + $relworxFailedAmount + $relworxPendingAmount,
            
            // Relworx transaction type breakdown
            'relworx_payments_count' => count($relworxPayments),
            'relworx_sends_count' => count($relworxSends),
            'relworx_products_count' => count($relworxProducts),
            'relworx_visa_count' => count($relworxVisa),
            
            // Relworx payment amounts by type
            'relworx_payments_amount' => array_sum(array_column($relworxPayments, 'amount')),
            'relworx_sends_amount' => array_sum(array_column($relworxSends, 'amount')),
            'relworx_products_amount' => array_sum(array_column($relworxProducts, 'amount')),
            'relworx_visa_amount' => array_sum(array_column($relworxVisa, 'amount')),
        ];

        if ($this->wantsJson()) {
            return $this->response->setJSON([
                'original' => [
                    'successful_count' => $data['successful_count'],
                    'failed_count' => $data['failed_count'],
                    'pending_count' => $data['pending_count'],
                    'successful_amount' => $data['successful_amount'],
                    'failed_amount' => $data['failed_amount'],
                    'pending_amount' => $data['pending_amount'],
                    'total_count' => $data['total_count'],
                    'total_amount' => $data['total_amount'],
                ],
                'relworx' => [
                    'successful_count' => $data['relworx_successful_count'],
                    'failed_count' => $data['relworx_failed_count'],
                    'pending_count' => $data['relworx_pending_count'],
                    'successful_amount' => $data['relworx_successful_amount'],
                    'failed_amount' => $data['relworx_failed_amount'],
                    'pending_amount' => $data['relworx_pending_amount'],
                    'total_count' => $data['relworx_total_count'],
                    'total_amount' => $data['relworx_total_amount'],
                    'payments_count' => $data['relworx_payments_count'],
                    'sends_count' => $data['relworx_sends_count'],
                    'products_count' => $data['relworx_products_count'],
                    'visa_count' => $data['relworx_visa_count'],
                ],
            ]);
        }
        return view('admin/dashboard', $data);
    }

    public function transactions()
    {
        // Check if user is logged in
        if (!session()->get('isLoggedIn')) {
            return redirect()->to(site_url('admin/login'));
        }

        $transactionModel = new TransactionModel();
        
        // Get filter parameters
        $status = $this->request->getGet('status');
        $search = $this->request->getGet('search');
        $startDate = $this->request->getGet('start_date');
        $endDate = $this->request->getGet('end_date');

        $builder = $transactionModel;

        // Apply filters
        if ($status && $status !== 'all') {
            $builder->where('status', $status);
        }

        if ($search) {
            $builder->groupStart()
                ->like('msisdn', $search)
                ->orLike('transaction_id', $search)
                ->groupEnd();
        }

        if ($startDate && $endDate) {
            $builder->where('created_at >=', $startDate . ' 00:00:00')
                   ->where('created_at <=', $endDate . ' 23:59:59');
        }

        $transactions = $builder->orderBy('created_at', 'DESC')->findAll();
        $data['transactions'] = $transactions;
        $data['status'] = $status;
        $data['search'] = $search;
        $data['start_date'] = $startDate;
        $data['end_date'] = $endDate;
        $data['system_type'] = 'original';

        // Financial stats for reporting (from current filter set)
        $data['stat_total'] = count($transactions);
        $data['stat_success_count'] = 0;
        $data['stat_failed_count'] = 0;
        $data['stat_pending_count'] = 0;
        $data['stat_success_amount'] = 0;
        $data['stat_failed_amount'] = 0;
        $data['stat_pending_amount'] = 0;
        foreach ($transactions as $t) {
            $amt = (float) ($t['amount'] ?? 0);
            $st = strtoupper($t['status'] ?? '');
            if ($st === 'SUCCESS') { $data['stat_success_count']++; $data['stat_success_amount'] += $amt; }
            elseif ($st === 'FAILED') { $data['stat_failed_count']++; $data['stat_failed_amount'] += $amt; }
            else { $data['stat_pending_count']++; $data['stat_pending_amount'] += $amt; }
        }

        return view('admin/transactions', $data);
    }

    public function relworxTransactions()
    {
        // Check if user is logged in
        if (!session()->get('isLoggedIn')) {
            return redirect()->to(site_url('admin/login'));
        }

        $paymentTransactionModel = new \App\Models\PaymentTransactionModel();
        $perPage = 20;

        // Get filter parameters
        $status = $this->request->getGet('status');
        $search = $this->request->getGet('search');
        $startDate = $this->request->getGet('start_date');
        $endDate = $this->request->getGet('end_date');
        $paymentMethod = $this->request->getGet('payment_method');

        // Apply filters to model for paginated list
        if ($status && $status !== 'all') {
            $paymentTransactionModel->where('status', $status);
        }
        if ($paymentMethod && $paymentMethod !== 'all') {
            $paymentTransactionModel->where('payment_method', $paymentMethod);
        }
        if ($search) {
            $paymentTransactionModel->groupStart()
                ->like('msisdn', $search)
                ->orLike('transaction_id', $search)
                ->orLike('reference', $search)
                ->groupEnd();
        }
        if ($startDate && $endDate) {
            $paymentTransactionModel->where('created_at >=', $startDate . ' 00:00:00')
                   ->where('created_at <=', $endDate . ' 23:59:59');
        }

        $transactions = $paymentTransactionModel->orderBy('created_at', 'DESC')->paginate($perPage);
        $data['transactions'] = $transactions;
        $data['pager'] = $paymentTransactionModel->pager;
        $data['status'] = $status;
        $data['search'] = $search;
        $data['start_date'] = $startDate;
        $data['end_date'] = $endDate;
        $data['payment_method'] = $paymentMethod;
        $data['system_type'] = 'relworx';

        // Financial stats from full filtered set (aggregate queries)
        $db = \Config\Database::connect();
        $statsBuilder = $db->table('payment_transactions');
        if ($status && $status !== 'all') {
            $statsBuilder->where('status', $status);
        }
        if ($paymentMethod && $paymentMethod !== 'all') {
            $statsBuilder->where('payment_method', $paymentMethod);
        }
        if ($search) {
            $statsBuilder->groupStart()
                ->like('msisdn', $search)
                ->orLike('transaction_id', $search)
                ->orLike('reference', $search)
                ->groupEnd();
        }
        if ($startDate && $endDate) {
            $statsBuilder->where('created_at >=', $startDate . ' 00:00:00')
                ->where('created_at <=', $endDate . ' 23:59:59');
        }
        $data['stat_total'] = $statsBuilder->countAllResults(false);
        $byStatus = $db->table('payment_transactions');
        if ($status && $status !== 'all') {
            $byStatus->where('status', $status);
        }
        if ($paymentMethod && $paymentMethod !== 'all') {
            $byStatus->where('payment_method', $paymentMethod);
        }
        if ($search) {
            $byStatus->groupStart()
                ->like('msisdn', $search)
                ->orLike('transaction_id', $search)
                ->orLike('reference', $search)
                ->groupEnd();
        }
        if ($startDate && $endDate) {
            $byStatus->where('created_at >=', $startDate . ' 00:00:00')
                ->where('created_at <=', $endDate . ' 23:59:59');
        }
        $rows = $byStatus->select('status, COUNT(*) as cnt, SUM(amount) as amt')->groupBy('status')->get()->getResultArray();
        $data['stat_success_count'] = 0;
        $data['stat_failed_count'] = 0;
        $data['stat_pending_count'] = 0;
        $data['stat_success_amount'] = 0;
        $data['stat_failed_amount'] = 0;
        $data['stat_pending_amount'] = 0;
        foreach ($rows as $r) {
            $st = strtoupper($r['status'] ?? '');
            $cnt = (int) ($r['cnt'] ?? 0);
            $amt = (float) ($r['amt'] ?? 0);
            if ($st === 'SUCCESS') {
                $data['stat_success_count'] = $cnt;
                $data['stat_success_amount'] = $amt;
            } elseif ($st === 'FAILED') {
                $data['stat_failed_count'] = $cnt;
                $data['stat_failed_amount'] = $amt;
            } else {
                $data['stat_pending_count'] += $cnt;
                $data['stat_pending_amount'] += $amt;
            }
        }
        $byMethod = $db->table('payment_transactions');
        if ($status && $status !== 'all') {
            $byMethod->where('status', $status);
        }
        if ($paymentMethod && $paymentMethod !== 'all') {
            $byMethod->where('payment_method', $paymentMethod);
        }
        if ($search) {
            $byMethod->groupStart()
                ->like('msisdn', $search)
                ->orLike('transaction_id', $search)
                ->orLike('reference', $search)
                ->groupEnd();
        }
        if ($startDate && $endDate) {
            $byMethod->where('created_at >=', $startDate . ' 00:00:00')
                ->where('created_at <=', $endDate . ' 23:59:59');
        }
        $methodRows = $byMethod->select('payment_method, COUNT(*) as cnt, SUM(amount) as amt')->groupBy('payment_method')->get()->getResultArray();
        $data['stat_by_method'] = [];
        foreach ($methodRows as $r) {
            $method = $r['payment_method'] ?? 'other';
            $data['stat_by_method'][$method] = [
                'count' => (int) ($r['cnt'] ?? 0),
                'amount' => (float) ($r['amt'] ?? 0),
            ];
        }

        return view('admin/relworx_transactions', $data);
    }

    public function filterTransactions()
    {
        // Check if user is logged in
        if (!session()->get('isLoggedIn')) {
            return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
        }

        $transactionModel = new TransactionModel();
        
        // Get filter parameters
        $status = $this->request->getGet('status');
        $search = $this->request->getGet('search');
        $startDate = $this->request->getGet('start_date');
        $endDate = $this->request->getGet('end_date');

        $builder = $transactionModel;

        // Apply filters
        if ($status && $status !== 'all') {
            $builder->where('status', $status);
        }

        if ($search) {
            $builder->groupStart()
                ->like('msisdn', $search)
                ->orLike('transaction_id', $search)
                ->groupEnd();
        }

        if ($startDate && $endDate) {
            $builder->where('created_at >=', $startDate . ' 00:00:00')
                   ->where('created_at <=', $endDate . ' 23:59:59');
        }

        $transactions = $builder->orderBy('created_at', 'DESC')->findAll();

        return $this->response->setJSON($transactions);
    }

    public function filterRelworxTransactions()
    {
        // Check if user is logged in
        if (!session()->get('isLoggedIn')) {
            return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
        }

        $paymentTransactionModel = new \App\Models\PaymentTransactionModel();
        
        // Get filter parameters
        $status = $this->request->getGet('status');
        $search = $this->request->getGet('search');
        $startDate = $this->request->getGet('start_date');
        $endDate = $this->request->getGet('end_date');
        $paymentMethod = $this->request->getGet('payment_method');

        $builder = $paymentTransactionModel;

        // Apply filters
        if ($status && $status !== 'all') {
            $builder->where('status', $status);
        }

        if ($paymentMethod && $paymentMethod !== 'all') {
            $builder->where('payment_method', $paymentMethod);
        }

        if ($search) {
            $builder->groupStart()
                ->like('msisdn', $search)
                ->orLike('transaction_id', $search)
                ->orLike('reference', $search)
                ->groupEnd();
        }

        if ($startDate && $endDate) {
            $builder->where('created_at >=', $startDate . ' 00:00:00')
                   ->where('created_at <=', $endDate . ' 23:59:59');
        }

        $transactions = $builder->orderBy('created_at', 'DESC')->findAll();

        return $this->response->setJSON($transactions);
    }

    public function exportTransactions()
    {
        // Check if user is logged in
        if (!session()->get('isLoggedIn')) {
            return redirect()->to(site_url('admin/login'));
        }

        $transactionModel = new TransactionModel();
        
        // Get filter parameters
        $status = $this->request->getGet('status');
        $search = $this->request->getGet('search');
        $startDate = $this->request->getGet('start_date');
        $endDate = $this->request->getGet('end_date');

        $builder = $transactionModel;

        // Apply filters
        if ($status && $status !== 'all') {
            $builder->where('status', $status);
        }

        if ($search) {
            $builder->groupStart()
                ->like('msisdn', $search)
                ->orLike('transaction_id', $search)
                ->groupEnd();
        }

        if ($startDate && $endDate) {
            $builder->where('created_at >=', $startDate . ' 00:00:00')
                   ->where('created_at <=', $endDate . ' 23:59:59');
        }

        $transactions = $builder->orderBy('created_at', 'DESC')->findAll();

        // Set headers for CSV download
        $filename = 'original_transactions_' . date('Y-m-d_H-i-s') . '.csv';
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Pragma: no-cache');
        header('Expires: 0');

        // Create CSV output
        $output = fopen('php://output', 'w');
        
        // Add headers
        fputcsv($output, ['ID', 'Transaction ID', 'MSISDN', 'Amount', 'Status', 'Created At']);
        
        // Add data
        foreach ($transactions as $transaction) {
            fputcsv($output, [
                $transaction['id'],
                $transaction['transaction_id'],
                $transaction['msisdn'],
                $transaction['amount'],
                $transaction['status'],
                $transaction['created_at']
            ]);
        }
        
        fclose($output);
        exit;
    }

    public function exportRelworxTransactions()
    {
        // Check if user is logged in
        if (!session()->get('isLoggedIn')) {
            return redirect()->to(site_url('admin/login'));
        }

        $paymentTransactionModel = new \App\Models\PaymentTransactionModel();
        
        // Get filter parameters
        $status = $this->request->getGet('status');
        $search = $this->request->getGet('search');
        $startDate = $this->request->getGet('start_date');
        $endDate = $this->request->getGet('end_date');
        $paymentMethod = $this->request->getGet('payment_method');

        $builder = $paymentTransactionModel;

        // Apply filters
        if ($status && $status !== 'all') {
            $builder->where('status', $status);
        }

        if ($paymentMethod && $paymentMethod !== 'all') {
            $builder->where('payment_method', $paymentMethod);
        }

        if ($search) {
            $builder->groupStart()
                ->like('msisdn', $search)
                ->orLike('transaction_id', $search)
                ->orLike('reference', $search)
                ->groupEnd();
        }

        if ($startDate && $endDate) {
            $builder->where('created_at >=', $startDate . ' 00:00:00')
                   ->where('created_at <=', $endDate . ' 23:59:59');
        }

        $transactions = $builder->orderBy('created_at', 'DESC')->findAll();

        // Set headers for CSV download
        $filename = 'relworx_transactions_' . date('Y-m-d_H-i-s') . '.csv';
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Pragma: no-cache');
        header('Expires: 0');

        // Create CSV output
        $output = fopen('php://output', 'w');
        
        // Add headers
        fputcsv($output, [
            'ID', 'Transaction ID', 'Reference', 'MSISDN', 'Amount', 'Currency', 
            'Status', 'Payment Method', 'Description', 'Gateway Reference', 
            'Client IP', 'Created At', 'Processed At'
        ]);
        
        // Add data
        foreach ($transactions as $transaction) {
            fputcsv($output, [
                $transaction['id'],
                $transaction['transaction_id'],
                $transaction['reference'],
                $transaction['msisdn'],
                $transaction['amount'],
                $transaction['currency'],
                $transaction['status'],
                $transaction['payment_method'],
                $transaction['description'],
                $transaction['gateway_reference'],
                $transaction['client_ip'],
                $transaction['created_at'],
                $transaction['processed_at']
            ]);
        }
        
        fclose($output);
        exit;
    }

    public function logout()
    {
        session()->destroy();
        return redirect()->to(site_url('admin/login'));
    }

    public function deleteFailedTransactions()
    {
        // Check if user is logged in
        if (!session()->get('isLoggedIn')) {
            return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
        }

        try {
            $transactionModel = new TransactionModel();
            
            // Get count of failed transactions before deletion
            $failedCount = $transactionModel->where('status', 'FAILED')->countAllResults();
            
            // Delete all failed transactions
            $result = $transactionModel->where('status', 'FAILED')->delete();
            
            if ($result) {
                return $this->response->setJSON([
                    'success' => true,
                    'message' => "Successfully deleted {$failedCount} failed transactions",
                    'deleted_count' => $failedCount
                ]);
            } else {
                return $this->response->setJSON([
                    'success' => false,
                    'message' => 'No failed transactions found to delete'
                ]);
            }
        } catch (\Exception $e) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Error deleting failed transactions: ' . $e->getMessage()
            ])->setStatusCode(500);
        }
    }

    public function markPendingAsFailed()
    {
        // Check if user is logged in
        if (!session()->get('isLoggedIn')) {
            return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
        }

        try {
            $transactionModel = new TransactionModel();
            
            // Get count of pending transactions before update
            $pendingCount = $transactionModel->where('status', 'PENDING')->countAllResults();
            
            // Update all pending transactions to failed
            $result = $transactionModel->where('status', 'PENDING')->set(['status' => 'FAILED'])->update();
            
            if ($result) {
                return $this->response->setJSON([
                    'success' => true,
                    'message' => "Successfully marked {$pendingCount} pending transactions as failed",
                    'updated_count' => $pendingCount
                ]);
            } else {
                return $this->response->setJSON([
                    'success' => false,
                    'message' => 'No pending transactions found to update'
                ]);
            }
        } catch (\Exception $e) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Error updating pending transactions: ' . $e->getMessage()
            ])->setStatusCode(500);
        }
    }

    public function deleteFailedRelworxTransactions()
    {
        // Check if user is logged in
        if (!session()->get('isLoggedIn')) {
            return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
        }

        try {
            $paymentTransactionModel = new \App\Models\PaymentTransactionModel();
            
            // Get count of failed transactions before deletion
            $failedCount = $paymentTransactionModel->where('status', 'FAILED')->countAllResults();
            
            // Delete all failed transactions
            $result = $paymentTransactionModel->where('status', 'FAILED')->delete();
            
            if ($result) {
                return $this->response->setJSON([
                    'success' => true,
                    'message' => "Successfully deleted {$failedCount} failed Relworx transactions",
                    'deleted_count' => $failedCount
                ]);
            } else {
                return $this->response->setJSON([
                    'success' => false,
                    'message' => 'No failed Relworx transactions found to delete'
                ]);
            }
        } catch (\Exception $e) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Error deleting failed Relworx transactions: ' . $e->getMessage()
            ])->setStatusCode(500);
        }
    }

    public function markPendingRelworxAsFailed()
    {
        // Check if user is logged in
        if (!session()->get('isLoggedIn')) {
            return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
        }

        try {
            $paymentTransactionModel = new \App\Models\PaymentTransactionModel();
            
            // Get count of pending transactions before update
            $pendingCount = $paymentTransactionModel->where('status', 'PENDING')->countAllResults();
            
            // Update all pending transactions to failed
            $result = $paymentTransactionModel->where('status', 'PENDING')->set(['status' => 'FAILED'])->update();
            
            if ($result) {
                return $this->response->setJSON([
                    'success' => true,
                    'message' => "Successfully marked {$pendingCount} pending Relworx transactions as failed",
                    'updated_count' => $pendingCount
                ]);
            } else {
                return $this->response->setJSON([
                    'success' => false,
                    'message' => 'No pending Relworx transactions found to update'
                ]);
            }
        } catch (\Exception $e) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Error updating pending Relworx transactions: ' . $e->getMessage()
            ])->setStatusCode(500);
        }
    }

    public function updateRelworxStatus($transactionId)
    {
        // Check if user is logged in
        if (!session()->get('isLoggedIn')) {
            return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
        }

        // Get status from POST data
        $status = $this->request->getPost('status');

        // Validate status
        if (!$status || !in_array($status, ['SUCCESS', 'FAILED'])) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Invalid status. Must be SUCCESS or FAILED'
            ])->setStatusCode(400);
        }

        try {
            $paymentTransactionModel = new \App\Models\PaymentTransactionModel();
            
            // Update the status using transaction_id
            $result = $paymentTransactionModel->where('transaction_id', $transactionId)->set(['status' => $status])->update();

            if (!$result) {
                return $this->response->setJSON([
                    'success' => false,
                    'message' => 'Transaction not found or not updated'
                ])->setStatusCode(404);
            }

            return $this->response->setJSON([
                'success' => true,
                'message' => 'Status updated successfully'
            ]);
        } catch (\Exception $e) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Failed to update status: ' . $e->getMessage()
            ])->setStatusCode(500);
        }
    }

    /**
     * Mobile Money Disbursements Page
     */
    public function disbursements()
    {
        // Check if user is logged in
        if (!session()->get('isLoggedIn')) {
            return redirect()->to(site_url('admin/login'));
        }

        return view('admin/disbursements');
    }

    /**
     * Cardyfie Customers Page
     */
    public function cardyfieCustomers()
    {
        // Check if user is logged in
        if (!session()->get('isLoggedIn')) {
            return redirect()->to(site_url('admin/login'));
        }

        $cardyfieService = new \App\Libraries\CardyfieService();
        
        // Get customers - Note: Cardyfie API doesn't have a list customers endpoint
        // We'll need to store customers in our database or fetch from API if available
        // For now, we'll show a message that customers need to be tracked separately
        
        $data = [
            'customers' => [], // Will be populated from database if we create a customers table
            'message' => 'Customer management requires database tracking. Customers are created via API.'
        ];

        return view('admin/cardyfie_customers', $data);
    }

    /**
     * Cardyfie Cards Page
     */
    public function cardyfieCards()
    {
        if (!session()->get('isLoggedIn')) {
            if ($this->wantsJson()) {
                return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
            }
            return redirect()->to(site_url('admin/login'));
        }

        $cardyfieService = new \App\Libraries\CardyfieService();
        
        // Get pagination parameters
        $page = (int) ($this->request->getGet('page') ?? 1);
        $perPage = (int) ($this->request->getGet('per_page') ?? 20);
        
        // Get cards from API
        $result = $cardyfieService->getCards($page, $perPage);
        
        $data = [
            'cards' => $result['success'] ? ($result['cards'] ?? []) : [],
            'pagination' => $result['success'] ? ($result['pagination'] ?? []) : [],
            'error' => $result['success'] ? null : $result['message'],
            'page' => $page,
            'per_page' => $perPage
        ];

        if ($this->wantsJson()) {
            return $this->response->setJSON($data);
        }
        return view('admin/cardyfie_cards', $data);
    }

    /**
     * Cardyfie Transactions Page
     */
    public function cardyfieTransactions()
    {
        if (!session()->get('isLoggedIn')) {
            if ($this->wantsJson()) {
                return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
            }
            return redirect()->to(site_url('admin/login'));
        }

        $cardyfieService = new \App\Libraries\CardyfieService();
        
        // Get filter parameters
        $cardUlid = $this->request->getGet('card_ulid');
        
        // Get transactions from API
        $result = $cardyfieService->getCardTransactions($cardUlid);
        
        $data = [
            'transactions' => $result['success'] ? ($result['transactions'] ?? []) : [],
            'error' => $result['success'] ? null : $result['message'],
            'card_ulid' => $cardUlid,
            'count' => $result['success'] ? ($result['count'] ?? 0) : 0
        ];

        if ($this->wantsJson()) {
            return $this->response->setJSON($data);
        }
        return view('admin/cardyfie_transactions', $data);
    }

    /**
     * Cardyfie Card Details and Management Page
     */
    public function cardyfieCardDetails($ulid = null)
    {
        if (!session()->get('isLoggedIn')) {
            if ($this->wantsJson()) {
                return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
            }
            return redirect()->to(site_url('admin/login'));
        }

        if (!$ulid) {
            $ulid = $this->request->getGet('ulid');
        }

        if (!$ulid) {
            if ($this->wantsJson()) {
                return $this->response->setJSON(['error' => 'Card ULID is required'])->setStatusCode(400);
            }
            session()->setFlashdata('error', 'Card ULID is required');
            return redirect()->to(site_url('admin/cardyfie-cards'));
        }

        $cardyfieService = new \App\Libraries\CardyfieService();
        
        // Get card details
        $cardResult = $cardyfieService->getCardDetails($ulid);
        
        // Get card transactions
        $transactionsResult = $cardyfieService->getCardTransactions($ulid);
        
        $data = [
            'card' => $cardResult['success'] ? ($cardResult['card'] ?? null) : null,
            'transactions' => $transactionsResult['success'] ? ($transactionsResult['transactions'] ?? []) : [],
            'error' => $cardResult['success'] ? null : $cardResult['message'],
            'card_ulid' => $ulid
        ];

        if ($this->wantsJson()) {
            return $this->response->setJSON($data);
        }
        return view('admin/cardyfie_card_details', $data);
    }

    /**
     * AJAX endpoint to perform card actions (freeze, unfreeze, close, deposit, withdraw)
     */
    public function cardyfieCardAction()
    {
        // Check if user is logged in
        if (!session()->get('isLoggedIn')) {
            return $this->response->setJSON(['success' => false, 'message' => 'Unauthorized'])->setStatusCode(401);
        }

        $cardyfieService = new \App\Libraries\CardyfieService();
        
        $action = $this->request->getPost('action');
        $cardUlid = $this->request->getPost('card_ulid');
        
        if (!$cardUlid) {
            return $this->response->setJSON(['success' => false, 'message' => 'Card ULID is required']);
        }

        $result = null;
        
        switch ($action) {
            case 'freeze':
                $result = $cardyfieService->freezeCard($cardUlid);
                break;
            case 'unfreeze':
                $result = $cardyfieService->unfreezeCard($cardUlid);
                break;
            case 'close':
                $result = $cardyfieService->closeCard($cardUlid);
                break;
            case 'deposit':
                $amount = (float) $this->request->getPost('amount');
                if ($amount <= 0) {
                    return $this->response->setJSON(['success' => false, 'message' => 'Amount must be greater than zero']);
                }
                $result = $cardyfieService->depositToCard($cardUlid, $amount);
                break;
            case 'withdraw':
                $amount = (float) $this->request->getPost('amount');
                if ($amount <= 0) {
                    return $this->response->setJSON(['success' => false, 'message' => 'Amount must be greater than zero']);
                }
                $result = $cardyfieService->withdrawFromCard($cardUlid, $amount);
                break;
            default:
                return $this->response->setJSON(['success' => false, 'message' => 'Invalid action']);
        }

        return $this->response->setJSON($result);
    }

    /**
     * NOWPayments dashboard: crypto balance, fiat payout list, payment / crypto payout lookup (live API).
     */
    public function nowpayments()
    {
        if (!session()->get('isLoggedIn')) {
            if ($this->wantsJson()) {
                return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
            }

            return redirect()->to(site_url('admin/login'));
        }

        $svc = new \App\Libraries\NowPaymentsService();
        $apiKeyOk = $svc->isConfigured();
        $bearerOk = $svc->isBearerConfigured();

        $balanceResult = $apiKeyOk ? $svc->getBalance() : null;

        $fiatQuery = [];
        foreach (['status', 'provider', 'limit', 'page', 'id', 'requestId', 'fiatCurrency', 'cryptoCurrency', 'dateFrom', 'dateTo'] as $k) {
            $v = $this->request->getGet($k);
            if ($v !== null && $v !== '') {
                $fiatQuery[$k] = $v;
            }
        }
        $fiatListResult = $bearerOk ? $svc->fiatPayoutList($fiatQuery) : null;

        $paymentId = trim((string) $this->request->getGet('payment_id'));
        $paymentLookup = ($paymentId !== '' && $apiKeyOk) ? $svc->getPaymentStatus($paymentId) : null;

        $cryptoPayoutId = trim((string) $this->request->getGet('crypto_payout_id'));
        $cryptoPayoutLookup = ($cryptoPayoutId !== '' && $apiKeyOk) ? $svc->getPayoutStatus($cryptoPayoutId) : null;

        $fiatProvidersResult = $bearerOk ? $svc->fiatPayoutProviders() : null;

        $data = [
            'api_key_configured' => $apiKeyOk,
            'bearer_configured' => $bearerOk,
            'bearer_static' => $svc->isBearerStaticConfigured(),
            'bearer_via_auth' => $svc->isAuthPasswordConfigured(),
            'ipn_secret_configured' => $svc->isIpnSecretConfigured(),
            'nowpayments_ipn_url' => site_url('api/nowpayments/ipn'),
            'balance_result' => $balanceResult,
            'fiat_list_result' => $fiatListResult,
            'fiat_filters' => [
                'status' => $this->request->getGet('status'),
                'provider' => $this->request->getGet('provider'),
                'limit' => $this->request->getGet('limit'),
                'page' => $this->request->getGet('page'),
                'id' => $this->request->getGet('id'),
                'requestId' => $this->request->getGet('requestId'),
                'fiatCurrency' => $this->request->getGet('fiatCurrency'),
                'cryptoCurrency' => $this->request->getGet('cryptoCurrency'),
                'dateFrom' => $this->request->getGet('dateFrom'),
                'dateTo' => $this->request->getGet('dateTo'),
            ],
            'payment_lookup' => $paymentLookup,
            'payment_id_input' => $paymentId,
            'crypto_payout_lookup' => $cryptoPayoutLookup,
            'crypto_payout_id_input' => $cryptoPayoutId,
            'fiat_providers_result' => $fiatProvidersResult,
        ];

        if ($this->wantsJson()) {
            return $this->response->setJSON($data);
        }

        return view('admin/nowpayments', $data);
    }

    /**
     * YEM / YEMChain dashboard view (globals, asset stats, balance lookup).
     */
    public function yem()
    {
        if (!session()->get('isLoggedIn')) {
            if ($this->wantsJson()) {
                return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
            }
            return redirect()->to(site_url('admin/login'));
        }

        $yemscanService = new \App\Libraries\YemscanService();
        $configured = $yemscanService->isConfigured();

        $globals = [];
        $assetStats = [];
        $volume = [];

        if ($configured) {
            $gr = $yemscanService->getGlobals();
            $globals = $gr['success'] ? $gr : [];
            $as = $yemscanService->getAssetStats('YEM');
            $assetStats = $as['success'] ? $as : [];
            $vol = $yemscanService->getTransactionVolume('YEM');
            $volume = $vol['success'] ? $vol : [];
        }

        $yemFilters = $this->getYemFilterParamsFromRequest(false);
        $yemFiltersActive = $this->yemFiltersActive($yemFilters);

        $perPage = 20;
        $page = max(1, (int) $this->request->getGet('page'));

        $yemTransactionModel = new \App\Models\YemTransactionModel();
        $this->applyYemTransactionFilters($yemTransactionModel, $yemFilters);
        try {
            $yemTransactions = $yemTransactionModel->orderBy('created_at', 'DESC')->paginate($perPage, 'default', $page);
            $yemPager = $yemTransactionModel->pager;
        } catch (\Throwable $e) {
            $yemTransactions = [];
            $yemPager = null;
        }

        // Auto-refresh statuses from API when loading the page (throttled: once per 2 minutes)
        if ($configured) {
            $cache = \Config\Services::cache();
            $lastRefresh = $cache->get('yem_status_last_refresh');
            $throttleSeconds = 120;
            if ($lastRefresh === null || (time() - (int) $lastRefresh) >= $throttleSeconds) {
                try {
                    $refreshModel = new \App\Models\YemTransactionModel();
                    $refreshModel->refreshStatuses($yemscanService, 100);
                    $cache->save('yem_status_last_refresh', time(), $throttleSeconds);
                    $yemTransactionModel = new \App\Models\YemTransactionModel();
                    $this->applyYemTransactionFilters($yemTransactionModel, $yemFilters);
                    $yemTransactions = $yemTransactionModel->orderBy('created_at', 'DESC')->paginate($perPage, 'default', $page);
                    $yemPager = $yemTransactionModel->pager;
                } catch (\Throwable $e) {
                    // ignore; page still shows existing data
                }
            }
        }

        $data = [
            'configured' => $configured,
            'globals' => $globals,
            'assetStats' => $assetStats,
            'volume' => $volume,
            'yemTransactions' => $yemTransactions,
            'yemPager' => $yemPager,
            'yem_filters' => $yemFilters,
            'yem_filters_active' => $yemFiltersActive,
        ];

        if ($this->wantsJson()) {
            return $this->response->setJSON($data);
        }
        return view('admin/yem', $data);
    }

    /**
     * Refresh YEM transaction statuses from API and update DB. Redirects back to admin/yem.
     */
    public function yemRefreshStatus()
    {
        if (!session()->get('isLoggedIn')) {
            if ($this->wantsJson()) {
                return $this->response->setJSON(['error' => 'Unauthorized'])->setStatusCode(401);
            }
            return redirect()->to(site_url('admin/login'));
        }
        $yemTransactionModel = new \App\Models\YemTransactionModel();
        $yemscanService = new \App\Libraries\YemscanService();
        $updated = $yemTransactionModel->refreshStatuses($yemscanService, 100);
        if ($this->wantsJson()) {
            return $this->response->setJSON(['updated' => $updated]);
        }
        $page = max(1, (int) $this->request->getPost('page'));
        $f = $this->getYemFilterParamsFromRequest(true);
        $query = [];
        foreach (['start_date', 'end_date', 'uid', 'reason', 'hash', 'status', 'asset', 'value_min', 'value_max'] as $key) {
            $v = $f[$key] ?? null;
            if ($v === null || $v === '') {
                continue;
            }
            if ($key === 'status' && $v === 'all') {
                continue;
            }
            $query[$key] = $v;
        }
        if ($page > 1) {
            $query['page'] = $page;
        }
        $url = site_url('admin/yem');
        if ($query !== []) {
            $url .= '?' . http_build_query($query);
        }
        return redirect()->to($url)->with('yem_status_refreshed', $updated);
    }
}
