<?php

namespace App\Controllers;

use CodeIgniter\RESTful\ResourceController;
use App\Libraries\PaytotaService;

/**
 * Simplified Paytota API endpoints.
 * POST /api/paytota/checkout, GET balance, GET purchase/status/:id, POST payout, POST payout/execute, GET payout/status/:id, POST webhook, GET health.
 */
class Paytota extends ResourceController
{
    protected $paytotaService;

    public function __construct()
    {
        $this->paytotaService = new PaytotaService();
    }

    /**
     * Simple checkout - create purchase and return checkout_url for redirect.
     * POST /api/paytota/checkout
     */
    public function checkout()
    {
        $json = $this->request->getJSON(true);
        if (!$json) {
            $json = $this->request->getPost();
        }
        if (empty($json)) {
            return $this->respond(['success' => false, 'message' => 'Invalid or empty JSON body'], 400);
        }

        $required = ['email', 'phone', 'country', 'currency', 'products', 'reference', 'success_redirect', 'failure_redirect'];
        foreach ($required as $field) {
            if ($field === 'products') {
                if (empty($json['products']) || !is_array($json['products'])) {
                    return $this->respond(['success' => false, 'message' => 'products must be a non-empty array of {name, price}'], 400);
                }
                continue;
            }
            if (!isset($json[$field]) || (is_string($json[$field]) && trim($json[$field]) === '')) {
                return $this->respond(['success' => false, 'message' => "Missing required field: {$field}"], 400);
            }
        }

        $result = $this->paytotaService->createPurchase($json);
        $code = $result['success'] ? 200 : 400;
        $response = [
            'success' => $result['success'],
            'message' => $result['message'],
        ];
        if (isset($result['data'])) {
            $response['data'] = $result['data'];
        }
        return $this->respond($response, $code);
    }

    /**
     * Get account balance.
     * GET /api/paytota/balance
     */
    public function balance()
    {
        $result = $this->paytotaService->getBalance();
        $code = $result['success'] ? 200 : 400;
        $response = [
            'success' => $result['success'],
            'message' => $result['message'],
        ];
        if (isset($result['data'])) {
            $response['data'] = $result['data'];
        }
        return $this->respond($response, $code);
    }

    /**
     * Get purchase status by id.
     * GET /api/paytota/purchase/status/:id
     */
    public function purchaseStatus($id = null)
    {
        if (empty($id)) {
            return $this->respond(['success' => false, 'message' => 'Purchase id is required'], 400);
        }
        $result = $this->paytotaService->getPurchaseStatus($id);
        $code = $result['success'] ? 200 : 400;
        $response = [
            'success' => $result['success'],
            'message' => $result['message'],
        ];
        if (isset($result['data'])) {
            $response['data'] = $result['data'];
        }
        return $this->respond($response, $code);
    }

    /**
     * Create payout (Step 1). Optionally include execute payload to run Step 2 in one call.
     * POST /api/paytota/payout
     */
    public function payout()
    {
        $json = $this->request->getJSON(true);
        if (!$json) {
            $json = $this->request->getPost();
        }
        if (empty($json)) {
            return $this->respond(['success' => false, 'message' => 'Invalid or empty JSON body'], 400);
        }

        $required = ['email', 'phone', 'country', 'currency', 'amount', 'description', 'reference'];
        foreach ($required as $field) {
            if (!isset($json[$field]) || (is_string($json[$field]) && trim((string) $json[$field]) === '')) {
                return $this->respond(['success' => false, 'message' => "Missing required field: {$field}"], 400);
            }
        }

        $payoutData = [
            'email' => $json['email'],
            'phone' => $json['phone'],
            'country' => $json['country'],
            'currency' => $json['currency'],
            'amount' => $json['amount'],
            'description' => $json['description'],
            'reference' => $json['reference'],
        ];
        if (!empty($json['bank_account'])) {
            $payoutData['bank_account'] = $json['bank_account'];
        }

        $result = $this->paytotaService->createPayout($payoutData);
        if (!$result['success']) {
            return $this->respond([
                'success' => false,
                'message' => $result['message'],
                'data' => $result['data'] ?? [],
            ], 400);
        }

        $executionUrl = $result['data']['execution_url'] ?? null;
        $executePayload = $json['execute'] ?? null;

        if ($executionUrl && !empty($executePayload) && is_array($executePayload) && !empty($executePayload['payout_type'])) {
            $execResult = $this->paytotaService->executePayout($executionUrl, $executePayload);
            return $this->respond([
                'success' => $execResult['success'],
                'message' => $execResult['message'],
                'data' => array_merge($result['data'], ['execute' => $execResult['data'] ?? []]),
            ], $execResult['success'] ? 200 : 400);
        }

        return $this->respond([
            'success' => true,
            'message' => $result['message'],
            'data' => $result['data'],
        ], 200);
    }

    /**
     * Execute payout Step 2 (separate call). Body: execution_url + payload (payout_type and bank or mobile fields).
     * POST /api/paytota/payout/execute
     */
    public function payoutExecute()
    {
        $json = $this->request->getJSON(true);
        if (!$json) {
            $json = $this->request->getPost();
        }
        if (empty($json)) {
            return $this->respond(['success' => false, 'message' => 'Invalid or empty JSON body'], 400);
        }
        if (empty($json['execution_url'])) {
            return $this->respond(['success' => false, 'message' => 'execution_url is required'], 400);
        }
        $payload = $json['payload'] ?? $json;
        unset($payload['execution_url']);
        if (empty($payload['payout_type'])) {
            return $this->respond(['success' => false, 'message' => 'payload.payout_type is required (bank or mobile)'], 400);
        }

        $result = $this->paytotaService->executePayout($json['execution_url'], $payload);
        $code = $result['success'] ? 200 : 400;
        $response = [
            'success' => $result['success'],
            'message' => $result['message'],
        ];
        if (isset($result['data'])) {
            $response['data'] = $result['data'];
        }
        return $this->respond($response, $code);
    }

    /**
     * Get payout status by id.
     * GET /api/paytota/payout/status/:id
     */
    public function payoutStatus($id = null)
    {
        if (empty($id)) {
            return $this->respond(['success' => false, 'message' => 'Payout id is required'], 400);
        }
        $result = $this->paytotaService->getPayoutStatus($id);
        $code = $result['success'] ? 200 : 400;
        $response = [
            'success' => $result['success'],
            'message' => $result['message'],
        ];
        if (isset($result['data'])) {
            $response['data'] = $result['data'];
        }
        return $this->respond($response, $code);
    }

    /**
     * Paytota webhook receiver (purchase.paid, purchase.error, payout.success, etc.).
     * POST /api/paytota/webhook
     */
    public function webhook()
    {
        $body = $this->request->getBody();
        $data = json_decode($body, true);
        if (!$data) {
            return $this->respond(['success' => false, 'message' => 'Invalid JSON'], 400);
        }

        log_message('info', 'Paytota webhook received: ' . ($data['event_type'] ?? 'unknown') . ' id=' . ($data['id'] ?? ''));

        // Optional: verify X-Signature using GET {base}/api/v1/public_key/ and RSA verify. For now acknowledge.
        return $this->respond(['success' => true, 'message' => 'Webhook received'], 200);
    }

    /**
     * Health check - config and optional connectivity.
     * GET /api/paytota/health
     */
    public function health()
    {
        $configured = $this->paytotaService->isConfigured();
        return $this->respond([
            'success' => true,
            'message' => 'OK',
            'data' => [
                'configured' => $configured,
                'service' => 'paytota',
            ],
        ], 200);
    }

    /**
     * Execute STK push for a purchase (Step 2 after create purchase).
     * POST /api/paytota/stk
     * Body: { "purchase_id": "..." }
     */
    public function stk()
    {
        $json = $this->request->getJSON(true);
        if (!$json) {
            $json = $this->request->getPost();
        }
        if (empty($json['purchase_id'])) {
            return $this->respond(['success' => false, 'message' => 'purchase_id is required'], 400);
        }
        $result = $this->paytotaService->executeStk($json['purchase_id']);
        $code = $result['success'] ? 200 : 400;
        $response = [
            'success' => $result['success'],
            'message' => $result['message'],
        ];
        if (isset($result['data'])) {
            $response['data'] = $result['data'];
        }
        return $this->respond($response, $code);
    }
}
