<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Models\Asset;
use App\Models\Invoice;
use App\Support\ApiResponse;
use App\Support\AtomicAmount;
use App\Support\PaymentQr;
use Illuminate\Http\Request;

final class CheckoutController extends Controller
{
    public function show(string $paymentId)
    {
        $invoice = $this->findInvoice($paymentId);
        if (! $invoice) {
            return ApiResponse::error('CHECKOUT_NOT_FOUND', 'The requested checkout does not exist.', 404);
        }

        return ApiResponse::success($this->resource($invoice));
    }

    public function selectCurrency(Request $request, string $paymentId)
    {
        $invoice = $this->findInvoice($paymentId);
        if (! $invoice) {
            return ApiResponse::error('CHECKOUT_NOT_FOUND', 'The requested checkout does not exist.', 404);
        }
        if ($invoice->status !== 'waiting') {
            return ApiResponse::error('CHECKOUT_LOCKED', 'Currency can only be changed while the invoice is waiting.', 409);
        }

        $data = $request->validate(['pay_currency' => ['required', 'string', 'max:20']]);
        $asset = Asset::where('code', strtoupper($data['pay_currency']))->where('enabled', true)->first();
        if (! $asset) {
            return ApiResponse::error('UNSUPPORTED_CURRENCY', 'The requested asset or network is not enabled.', 422);
        }

        if ($asset->id !== $invoice->pay_asset_id) {
            return ApiResponse::error('CURRENCY_SWITCH_UNAVAILABLE', 'This sandbox checkout currently supports the original invoice currency only.', 409);
        }

        return ApiResponse::success($this->resource($invoice));
    }

    public function page(string $paymentId)
    {
        $invoice = $this->findInvoice($paymentId);
        if (! $invoice) {
            abort(404);
        }

        $data = $this->resource($invoice);
        $html = '<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Checkout '.$data['payment_id'].'</title><style>body{font-family:Arial,sans-serif;background:#f6f8fb;margin:0;color:#17202a}.wrap{max-width:760px;margin:48px auto;background:white;border:1px solid #d8dee9;padding:28px;border-radius:8px}.row{display:flex;justify-content:space-between;border-bottom:1px solid #edf0f5;padding:12px 0}.addr{font-family:monospace;word-break:break-all;background:#f1f4f8;padding:12px;border-radius:6px}.status{display:inline-block;padding:6px 10px;border-radius:999px;background:#fff3cd;color:#7a5a00}</style></head><body><main class="wrap"><h1>Crypto Checkout</h1><p class="status">'.e($data['status']).'</p><div class="row"><strong>Order</strong><span>'.e((string)$data['order_id']).'</span></div><div class="row"><strong>Amount</strong><span>'.e($data['price_amount'].' '.$data['price_currency']).'</span></div><div class="row"><strong>Pay</strong><span>'.e($data['pay_amount'].' '.$data['pay_currency']).'</span></div><div class="row"><strong>Network</strong><span>'.e($data['network']).'</span></div><h3>Send payment to</h3><p><img src="'.e($data['qr_code']['image_url']).'" alt="Payment QR" width="240" height="240"></p><p class="addr">'.e((string)$data['pay_address']).'</p><p>Expires at '.e((string)$data['expires_at']).'</p></main></body></html>';

        return response($html);
    }

    private function findInvoice(string $paymentId): ?Invoice
    {
        return Invoice::with(['asset', 'address'])->where('public_id', $paymentId)->first();
    }

    private function resource(Invoice $invoice): array
    {
        return [
            'payment_id' => $invoice->public_id,
            'order_id' => $invoice->order_id,
            'status' => $invoice->status,
            'price_amount' => number_format($invoice->price_amount_minor / 100, 2, '.', ''),
            'price_currency' => $invoice->price_currency,
            'pay_amount' => AtomicAmount::toDecimal((string) $invoice->quoted_pay_amount_atomic, $invoice->asset->decimals),
            'actually_paid' => AtomicAmount::toDecimal((string) $invoice->paid_amount_atomic, $invoice->asset->decimals),
            'pay_currency' => $invoice->asset->code,
            'network' => $invoice->asset->network,
            'pay_address' => $invoice->address?->address,
            'qr_code' => PaymentQr::forInvoice($invoice),
            'expires_at' => $invoice->expires_at?->utc()->toIso8601String(),
            'success_url' => $invoice->success_url,
            'cancel_url' => $invoice->cancel_url,
        ];
    }
}
