<?php
namespace app\controllers;

use app\app;
use app\models\invoices;
$invoice = 'lnbc234340n1pnm5uh2pp5pwekmjzj3hgadahfeprtc6f2ppmhnqjzh556q4fvve8z953v3t0sdqqcqzysxqrrsssp5uq25yjnmvdpnglmv42nf64wk0pugrynq549f3wgghgtkfapwdfhq9qxpqysgqyjq2ewqkm6s2dlhuruuc4k9md22wraz829tlhfeuxrsnwmephfkjz8e9g7j6373989mfccajy3cxexac8xu6yen4qfs4947fkrg9ynsq7x72ze';
use Jorijn\Bitcoin\Bolt11\Encoder\PaymentRequestDecoder;
use Jorijn\Bitcoin\Bolt11\Normalizer\PaymentRequestDenormalizer;

class lnurlp
{
    public static function index($defaults)
    {
        header(header: 'Content-Type: application/json');
        $username       = $_GET["username"] ?? false;
        $paymentRequest = $_GET["pay"] ?? false;
        $verify         = $_GET["verify"] ?? false;

        function returnJson($arr): never
        {
            echo json_encode(value: $arr);
            exit();
        }

        // for when the callback is used incorrectly
        if ($paymentRequest != 1 && $paymentRequest != false) {
            returnJson([
                'status' => 'ERROR',
                'reason' => 'invalid value for `pay` param (set `pay=1` or exclude `pay` from the url)',
            ]);
        }
        // for when the user is not specified
        if ($username == false && $verify == false) {
            returnJson([
                'status' => 'ERROR',
                'reason' => 'no user specified (set `username=<name>` in the url)',
            ]);
        }
        // for when the user is not registered
        $user = users::getByNpub($username);
        if (! $user) {
            returnJson([
                'status' => 'ERROR',
                'reason' => "@$username is not registered",
            ]);
        }
        // for when the client makes it's first call (querying the lightning address)
        list($proxy_user, $proxy_host) = explode("@", $_ENV['LN_ADDRESS']);
        $metadata                      = "[[\"text/plain\",\"Funding @$username on $host\"],[\"text/identifier\",\"$username@$host\"]]";
        if ($paymentRequest == false && $verify == false) {
            $res = json_decode(file_get_contents("https://$proxy_host/.well-known/lnurlp/$proxy_user"), true);
            returnJson(
                [
                    'callback'       => "https://$host/lnurlp?pay=1&username=$username",
                    'maxSendable'    => $res['maxSendable'],
                    'minSendable'    => $res['minSendable'],
                    'metadata'       => $metadata,
                    'commentAllowed' => $res['commentAllowed'],
                    'payerData'      => $res['payerData'],
                    'tag'            => "payRequest",
                ]
            );
        }

        // for when the client makes it's second call (callback) to get an invoice
        if ($paymentRequest == "1") {
            $res       = json_decode(file_get_contents("https://$proxy_host/.well-known/lnurlp/$proxy_user"), true);
            $proxy_url = $res['callback'];
            if (isset($_GET["amount"])) {
                $proxy_url .= "&amount=" . urlencode($_GET["amount"]);
            }
            $res = json_decode(file_get_contents($proxy_url), true);

            if ($res['status'] === 'OK') {
                // subscribe to this invoice by adding to our db
                $invoice        = $res['pr'];
                $decoder        = new PaymentRequestDecoder();
                $denormalizer   = new PaymentRequestDenormalizer();
                $paymentRequest = $denormalizer->denormalize($decoder->decode($invoice));
                invoices::add(
                    $user['id'],
                    null,
                    $invoice,
                    $res['verify'],
                    $paymentRequest->getMilliSatoshis(),
                    $paymentRequest->getExpiryDateTime()['date']
                );
                $boom         = explode("=", $res['verify']);
                $proxy_verify = end($boom);
                returnJson([
                    'status' => 'OK',
                    'pr'     => $invoice,
                    'routes' => $res['routes'],
                    'verify' => "https://$host/lnurlp?verify=$proxy_verify",
                ]);
            } else {
                returnJson($res);
            }
        }

        // for when they want to verify the payment succeeded
        if ($verify) {
            $res       = json_decode(file_get_contents("https://$proxy_host/.well-known/lnurlp/$proxy_user"), true);
            $proxy_url = $res['verify'];
            $prox_res  = json_decode(file_get_contents($proxy_url), true);
            returnJson($prox_res);
        }

        // for when none of the above conditions are met
        returnJson([
            'status' => 'ERROR',
            'reason' => 'unhandled error (how did you get here?)',
        ]);
    }
}
