<?php declare(strict_types=1);

namespace Lewisdale\Webmentions\Api;

use Lewisdale\Webmentions\Gateways\WebmentionGatewayInterface;
use Lewisdale\Webmentions\Router\Request;
use Lewisdale\Webmentions\Router\Response;
use Lewisdale\Webmentions\Router\StatusCode;

/**
 * API Controller for retrieving Webmentions
 */
class WebmentionApi
{
    function __construct(private readonly WebmentionGatewayInterface $gateway)
    {
    }

    // List Webmentions. Optionally filter by target.
    public function list(Request $request, Response $response)
    {
        if (!$this->verifyUser($request)) {
            $response->status_code = StatusCode::Unauthorized;
            return "Unauthorized";
        }

        $target = array_key_exists("post", $request->query) ? $request->query["post"] : null;
        $mentions = !empty($target) ? $this->gateway->getByPost($target) : $this->gateway->list();
        return $response->json($mentions);
    }

    // Get a webmention by ID
    public function get(Request $request, Response $response)
    {
        if (!$this->verifyUser($request)) {
            $response->status_code = StatusCode::Unauthorized;
            return "Unauthorized";
        }
        
        $id = (int)$request->params[0];

        if ($id) {
            $mention = $this->gateway->get($id);

            if ($mention) {
                $response->status_code = StatusCode::Ok;
                return $response->json($mention);
            }
        }

        $response->status_code = StatusCode::NotFound;
    }

    private function verifyUser(Request $request): bool
    {
        if (!array_key_exists("authorization", $request->headers)) {
            return false;
        }

        [, $auth] = explode("Basic ", $request->headers["authorization"]);

        if (empty($auth)) {
            return false;
        }

        [$username, $password] = explode(":", base64_decode($auth));

        if (!empty($username) && $username === $_ENV["USERNAME"] && !empty($password) && $password === $_ENV["PASSWORD"]) {
            return true;
        }

        return false;
    }
}