<?php

namespace App\Controllers\Api;

use App\Controllers\BaseController;
use App\Models\TransactionModel;
use App\Models\PaymentTransactionModel;
use App\Libraries\YemWithdrawalRequestActions;
use App\Models\YemTransactionModel;
use App\Models\YemWithdrawalRequestModel;

class AdminApiController extends BaseController
{
    private const TOKEN_PREFIX = 'admin_token_';
    private const TOKEN_TTL = 604800; // 7 days

    /**
     * POST api/admin/login - JSON body: {"username":"...","password":"..."}
     * Returns {"token":"...","username":"..."} or 401 {"error":"Invalid credentials"}
     */
    public function login()
    {
        $json = $this->request->getJSON(true);
        if (!is_array($json)) {
            $json = $this->request->getPost();
        }
        $username = is_array($json) ? ($json['username'] ?? '') : '';
        $password = is_array($json) ? ($json['password'] ?? '') : '';

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

        if ($username !== $adminUsername || $password !== $adminPassword) {
            return $this->response->setJSON(['error' => 'Invalid credentials'])->setStatusCode(401);
        }

        $token = bin2hex(random_bytes(32));
        $cache = \Config\Services::cache();
        $cache->save(self::TOKEN_PREFIX . $token, ['username' => $username], self::TOKEN_TTL);

        return $this->response->setJSON([
            'token' => $token,
            'username' => $username,
        ]);
    }

    /**
     * POST api/admin/logout - Requires Authorization: Bearer <token>
     */
    public function logout()
    {
        $token = $this->getBearerToken();
        if ($token) {
            $cache = \Config\Services::cache();
            $cache->delete(self::TOKEN_PREFIX . $token);
        }
        return $this->response->setJSON(['success' => true]);
    }

    /**
     * GET api/admin/dashboard - JSON stats (same as dashboard view)
     */
    public function dashboard()
    {
        $transactionModel = new TransactionModel();
        $paymentTransactionModel = new PaymentTransactionModel();

        $allTransactions = $transactionModel->findAll();
        $allRelworxTransactions = $paymentTransactionModel->findAll();

        $successfulCount = 0;
        $failedCount = 0;
        $pendingCount = 0;
        $successfulAmount = 0;
        $failedAmount = 0;
        $pendingAmount = 0;

        foreach ($allTransactions as $transaction) {
            $status = strtoupper($transaction['status']);
            $amount = (float) ($transaction['amount'] ?? 0);
            switch ($status) {
                case 'SUCCESS': $successfulCount++; $successfulAmount += $amount; break;
                case 'FAILED': $failedCount++; $failedAmount += $amount; break;
                case 'PENDING': $pendingCount++; $pendingAmount += $amount; break;
            }
        }

        $relworxSuccessfulCount = 0;
        $relworxFailedCount = 0;
        $relworxPendingCount = 0;
        $relworxSuccessfulAmount = 0;
        $relworxFailedAmount = 0;
        $relworxPendingAmount = 0;

        foreach ($allRelworxTransactions as $transaction) {
            $status = strtoupper($transaction['status']);
            $amount = (float) ($transaction['amount'] ?? 0);
            switch ($status) {
                case 'SUCCESS': $relworxSuccessfulCount++; $relworxSuccessfulAmount += $amount; break;
                case 'FAILED': $relworxFailedCount++; $relworxFailedAmount += $amount; break;
                case 'PENDING': $relworxPendingCount++; $relworxPendingAmount += $amount; break;
            }
        }

        $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' => [
                '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' => [
                'successful_count' => $relworxSuccessfulCount,
                'failed_count' => $relworxFailedCount,
                'pending_count' => $relworxPendingCount,
                'successful_amount' => $relworxSuccessfulAmount,
                'failed_amount' => $relworxFailedAmount,
                'pending_amount' => $relworxPendingAmount,
                'total_count' => $relworxSuccessfulCount + $relworxFailedCount + $relworxPendingCount,
                'total_amount' => $relworxSuccessfulAmount + $relworxFailedAmount + $relworxPendingAmount,
                'payments_count' => count($relworxPayments),
                'sends_count' => count($relworxSends),
                'products_count' => count($relworxProducts),
                'visa_count' => count($relworxVisa),
                'payments_amount' => array_sum(array_column($relworxPayments, 'amount')),
                'sends_amount' => array_sum(array_column($relworxSends, 'amount')),
                'products_amount' => array_sum(array_column($relworxProducts, 'amount')),
                'visa_amount' => array_sum(array_column($relworxVisa, 'amount')),
            ],
        ];

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

    /**
     * GET api/admin/cardyfie-cards?page=1&per_page=20
     */
    public function cardyfieCards()
    {
        $cardyfieService = new \App\Libraries\CardyfieService();
        $page = (int) ($this->request->getGet('page') ?? 1);
        $perPage = (int) ($this->request->getGet('per_page') ?? 20);
        $result = $cardyfieService->getCards($page, $perPage);
        $data = [
            'cards' => $result['success'] ? ($result['cards'] ?? []) : [],
            'pagination' => $result['success'] ? ($result['pagination'] ?? []) : [],
            'error' => $result['success'] ? null : ($result['message'] ?? 'Unknown error'),
        ];
        return $this->response->setJSON($data);
    }

    /**
     * GET api/admin/cardyfie-card?ulid=...
     */
    public function cardyfieCard()
    {
        $ulid = $this->request->getGet('ulid');
        if (!$ulid) {
            return $this->response->setJSON(['error' => 'ulid required'])->setStatusCode(400);
        }
        $cardyfieService = new \App\Libraries\CardyfieService();
        $cardResult = $cardyfieService->getCardDetails($ulid);
        $transactionsResult = $cardyfieService->getCardTransactions($ulid);
        $data = [
            'card' => $cardResult['success'] ? ($cardResult['card'] ?? null) : null,
            'transactions' => $transactionsResult['success'] ? ($transactionsResult['transactions'] ?? []) : [],
            'error' => $cardResult['success'] ? null : ($cardResult['message'] ?? 'Unknown error'),
        ];
        return $this->response->setJSON($data);
    }

    /**
     * GET api/admin/cardyfie-transactions?card_ulid=...
     */
    public function cardyfieTransactions()
    {
        $cardUlid = $this->request->getGet('card_ulid');
        $cardyfieService = new \App\Libraries\CardyfieService();
        $result = $cardyfieService->getCardTransactions($cardUlid);
        $data = [
            'transactions' => $result['success'] ? ($result['transactions'] ?? []) : [],
            'count' => $result['success'] ? ($result['count'] ?? 0) : 0,
            'error' => $result['success'] ? null : ($result['message'] ?? 'Unknown error'),
        ];
        return $this->response->setJSON($data);
    }

    /**
     * GET api/admin/yem - YEM dashboard data as JSON
     */
    public function yem()
    {
        $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 : [];
        }

        $yemTransactionModel = new YemTransactionModel();
        try {
            $yemTransactions = $yemTransactionModel->getAllOrderByCreatedDesc(200);
        } catch (\Throwable $e) {
            $yemTransactions = [];
        }

        $data = [
            'configured' => $configured,
            'globals' => $globals,
            'assetStats' => $assetStats,
            'volume' => $volume,
            'yemTransactions' => $yemTransactions,
        ];
        return $this->response->setJSON($data);
    }

    /**
     * POST api/admin/yem/refresh-status - Refresh YEM statuses, return JSON { updated: n }
     */
    public function yemRefreshStatus()
    {
        $yemTransactionModel = new YemTransactionModel();
        $yemscanService = new \App\Libraries\YemscanService();
        $updated = $yemTransactionModel->refreshStatuses($yemscanService, 100);
        return $this->response->setJSON(['updated' => $updated]);
    }

    /**
     * GET api/admin/yem-withdrawals — list withdrawal requests (newest first)
     */
    public function yemWithdrawals()
    {
        $model = new YemWithdrawalRequestModel();
        $requests = $model->orderBy('created_at', 'DESC')->findAll(500);

        return $this->response->setJSON(['requests' => $requests]);
    }

    /**
     * POST api/admin/yem-withdrawals/{id}/complete — mark pending request completed; sends FCM + email
     */
    public function yemWithdrawalComplete($id = null)
    {
        $id = (int) $id;
        $result = (new YemWithdrawalRequestActions())->markCompleted($id);

        return $this->response->setJSON($result)->setStatusCode($result['success'] ? 200 : 400);
    }

    /**
     * POST api/admin/yem-withdrawals/{id}/reject — body JSON: { "rejection_reason": "..." }; sends FCM + email with reason
     */
    public function yemWithdrawalReject($id = null)
    {
        $id = (int) $id;
        $json = $this->request->getJSON(true);
        $reason = '';
        if (is_array($json) && isset($json['rejection_reason'])) {
            $reason = (string) $json['rejection_reason'];
        }
        if ($reason === '') {
            $reason = (string) $this->request->getPost('rejection_reason');
        }

        $result = (new YemWithdrawalRequestActions())->markRejected($id, $reason);

        return $this->response->setJSON($result)->setStatusCode($result['success'] ? 200 : 400);
    }

    private function getBearerToken(): ?string
    {
        $auth = $this->request->getHeaderLine('Authorization');
        if (preg_match('/Bearer\s+(\S+)/', $auth, $m)) {
            return $m[1];
        }
        return null;
    }
}
