<?php

declare(strict_types=1);

require_once __DIR__ . '/../db.php';
require_once __DIR__ . '/../auth.php';

header('Content-Type: application/json; charset=utf-8');

function jsonResponse(array $data, int $status = 200): void
{
    http_response_code($status);
    echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    exit;
}

function getInputData(): array
{
    $contentType = $_SERVER['CONTENT_TYPE'] ?? '';

    if (str_contains($contentType, 'application/json')) {
        $raw = file_get_contents('php://input');
        $data = json_decode($raw, true);

        return is_array($data) ? $data : [];
    }

    return $_POST;
}

function getBearerTokenFromHeader(): ?string
{
    $header = $_SERVER['HTTP_AUTHORIZATION'] ?? '';

    if (preg_match('/Bearer\s+(.+)/', $header, $matches)) {
        return trim($matches[1]);
    }

    return null;
}

$api = $_GET['api'] ?? '';

switch ($api) {

    case 'Login': {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            jsonResponse([
                'success' => false,
                'error' => 'Login requires POST.'
            ], 405);
        }

        $data = getInputData();

        $email = trim($data['email'] ?? '');
        $password = (string)($data['password'] ?? '');

        if ($email === '' || $password === '') {
            jsonResponse([
                'success' => false,
                'error' => 'Email and password are required.'
            ], 400);
        }

        $token = login($email, $password, false);

        if ($token === null) {
            jsonResponse([
                'success' => false,
                'error' => 'Invalid email or password.'
            ], 401);
        }

        $user = currentUser();

        jsonResponse([
            'success' => true,
            'token_type' => 'Bearer',
            'access_token' => $token,
            'expires_in' => 43200,
            'user' => $user
        ]);
    }

    case 'CreateToken': {
        $user = currentUser();

        if (!$user) {
            jsonResponse([
                'success' => false,
                'error' => 'Not logged in.'
            ], 401);
        }

        $token = createAuthToken((int)$user['id']);

        jsonResponse([
            'success' => true,
            'token_type' => 'Bearer',
            'access_token' => $token,
            'expires_in' => 43200,
            'user' => $user
        ]);
    }

    case 'Me': {
        $token = getBearerTokenFromHeader();

        if ($token) {
            $user = authenticateApiToken($token);
        } else {
            $user = currentUser();
        }

        if (!$user) {
            jsonResponse([
                'success' => false,
                'error' => 'Not authenticated.'
            ], 401);
        }

        jsonResponse([
            'success' => true,
            'user' => $user
        ]);
    }

    case 'Logout': {
        $token = getBearerTokenFromHeader();

        if ($token) {
            $tokenHash = hash('sha256', $token);

            db()->prepare(
                'UPDATE auth_tokens
                 SET revoked_at = NOW()
                 WHERE token_hash = ?
                   AND revoked_at IS NULL'
            )->execute([$tokenHash]);

            jsonResponse([
                'success' => true
            ]);
        }

        logout();

        jsonResponse([
            'success' => true
        ]);
    }

    default: {
        jsonResponse([
            'success' => false,
            'error' => 'Unknown API action.'
        ], 404);
    }
}