<?php

require __DIR__ . '/KingsmenPay.php';

$config = require __DIR__ . '/config.php';
$client = new KingsmenPay($config);

try {
    $method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
    $path = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);

    if ($method === 'GET' && $path === '/health') {
        send_json(['status' => 'ok']);
    }

    if ($method !== 'POST') {
        send_json(['error' => 'Method not allowed'], 405);
    }

    $body = read_body();

    if ($path === '/api/payin') {
        require_fields($body, ['orderid', 'money']);
        send_json($client->createPayin($body));
    }

    if ($path === '/api/payout') {
        require_fields($body, ['orderid', 'money', 'account']);
        require_any_field($body, ['userName', 'username']);
        require_any_field($body, ['reserve1', 'ifsc']);
        send_json($client->createPayout($body));
    }

    if ($path === '/api/payin/status') {
        require_fields($body, ['orderid']);
        send_json($client->queryPayinStatus((string) $body['orderid']));
    }

    if ($path === '/api/payout/status') {
        require_fields($body, ['orderid']);
        send_json($client->queryPayoutStatus((string) $body['orderid']));
    }

    if ($path === '/api/balance') {
        send_json($client->queryBalance((string) ($body['currency'] ?? 'INR')));
    }

    if ($path === '/webhooks/payin' || $path === '/webhooks/payout') {
        $verified = $client->verifyCallbackSignature($body);
        store_callback($path, $body, $verified);
        header('Content-Type: text/plain; charset=utf-8');
        echo 'success';
        exit;
    }

    send_json(['error' => 'Route not found'], 404);
} catch (Throwable $error) {
    $statusCode = $error instanceof InvalidArgumentException ? 400 : 500;
    send_json(['error' => $error->getMessage()], $statusCode);
}

function read_body(): array
{
    $raw = file_get_contents('php://input');
    $contentType = $_SERVER['CONTENT_TYPE'] ?? '';

    if (str_contains($contentType, 'application/json')) {
        $decoded = json_decode($raw ?: '{}', true);
        if (!is_array($decoded)) {
            throw new InvalidArgumentException('Invalid JSON request body');
        }
        return $decoded;
    }

    parse_str($raw, $parsed);
    return $parsed;
}

function require_fields(array $body, array $fields): void
{
    $missing = [];
    foreach ($fields as $field) {
        if (!isset($body[$field]) || $body[$field] === '') {
            $missing[] = $field;
        }
    }

    if ($missing !== []) {
        throw new InvalidArgumentException('Missing required field(s): ' . implode(', ', $missing));
    }
}

function require_any_field(array $body, array $fields): void
{
    foreach ($fields as $field) {
        if (isset($body[$field]) && $body[$field] !== '') {
            return;
        }
    }

    throw new InvalidArgumentException('Missing one of required field(s): ' . implode(', ', $fields));
}

function send_json(array $payload, int $statusCode = 200): void
{
    http_response_code($statusCode);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($payload);
    exit;
}

function store_callback(string $path, array $body, bool $verified): void
{
    $dir = dirname(__DIR__) . '/storage';
    if (!is_dir($dir)) {
        mkdir($dir, 0775, true);
    }

    $record = [
        'type' => str_ends_with($path, '/payin') ? 'payin' : 'payout',
        'verified' => $verified,
        'body' => $body,
        'receivedAt' => gmdate('c'),
    ];

    file_put_contents($dir . '/callbacks.log', json_encode($record) . PHP_EOL, FILE_APPEND);
}
