<?php

use MintyPHP\Http\ApiAuth;
use MintyPHP\Http\ApiBootstrap;
use MintyPHP\Http\ApiResponse;
use MintyPHP\Service\Auth\ApiTokenEndpointService;
use MintyPHP\Service\Auth\AuthServicesFactory;

ApiBootstrap::init();
$apiTokenService = (app(AuthServicesFactory::class))->createApiTokenService();
$apiTokenEndpointService = app(ApiTokenEndpointService::class);
$request = requestInput();

$userId = ApiAuth::userId();
if ($userId <= 0) {
    ApiResponse::unauthorized();
}

ApiAuth::requireSelfManageTokens();

$method = $request->method();

if ($method === 'GET') {
    $limit = $apiTokenEndpointService->normalizeLimit($request->queryInt('limit', 50));
    $scopedTenantId = ApiAuth::scopedTenantId();
    $rows = $apiTokenEndpointService->listSelfTokens($userId, $limit, $scopedTenantId, ApiAuth::tokenId());

    ApiResponse::success([
        'data' => $rows,
        'limit' => $limit,
    ]);
}

if ($method === 'POST') {
    $input = $request->bodyAll();

    $name = trim((string) ($input['name'] ?? ''));
    if ($name === '') {
        ApiResponse::validationFromFormErrors(formErrorsFrom(['name' => [t('Token name is required')]]));
    }
    if (array_key_exists('tenant_id', $input)) {
        ApiResponse::validationFromFormErrors(formErrorsFrom(['tenant_id' => ['use_tenant_uuid']]));
    }

    $tenantResolution = $apiTokenEndpointService->resolveSelfCreateTenant(
        $userId,
        ApiAuth::scopedTenantId(),
        trim((string) ($input['tenant_uuid'] ?? ''))
    );
    if (!($tenantResolution['ok'] ?? false)) {
        $status = (int) ($tenantResolution['status'] ?? 422);
        $error = (string) ($tenantResolution['error'] ?? 'invalid_tenant_uuid');
        $field = trim((string) ($tenantResolution['field'] ?? ''));
        if ($status === 403) {
            ApiResponse::forbidden($error);
        }
        if ($field !== '') {
            ApiResponse::validationFromFormErrors(formErrorsFrom([$field => [$error]]));
        }
        ApiResponse::error($error, $status);
    }
    $tenantId = array_key_exists('tenant_id', $tenantResolution) ? (int) ($tenantResolution['tenant_id'] ?? 0) : null;
    if ($tenantId !== null && $tenantId <= 0) {
        $tenantId = null;
    }
    $tenantUuid = (string) ($tenantResolution['tenant_uuid'] ?? '') ?: null;

    $expiresParse = $apiTokenEndpointService->parseExpiresAt((string) ($input['expires_at'] ?? ''));
    if (!($expiresParse['ok'] ?? false)) {
        ApiResponse::validationFromFormErrors(formErrorsFrom(['expires_at' => [(string) ($expiresParse['error'] ?? 'invalid_datetime')]]));
    }
    $expiresAt = $expiresParse['expires_at'] ?? null;

    $currentTokenRecord = ApiAuth::tokenRecord();
    $expiresAt = $apiTokenEndpointService->capExpiryToParent($expiresAt, (string) ($currentTokenRecord['expires_at'] ?? ''));

    $result = $apiTokenService->create($userId, $name, $tenantId, $expiresAt, $userId);
    if (!($result['ok'] ?? false)) {
        $error = (string) ($result['error'] ?? 'create_failed');
        if ($error === 'tenant_not_assigned') {
            ApiResponse::forbidden($error);
        }
        if ($error === 'max_tokens_reached') {
            ApiResponse::error($error, 409);
        }
        ApiResponse::error($error, 422);
    }

    ApiResponse::success([
        'data' => [
            'token_uuid' => (string) ($result['uuid'] ?? ''),
            'token' => (string) ($result['token'] ?? ''),
            'selector_prefix' => substr((string) ($result['selector'] ?? ''), 0, 8),
            'tenant_uuid' => $tenantUuid,
            'expires_at' => $result['expires_at'] ?? null,
        ],
    ], 201);
}

ApiResponse::methodNotAllowed();
