<?php

declare(strict_types=1);

namespace ApiModel\Shared\Http;

use ApiModel\Shared\RequestContext;

final class ErrorResponse
{
    /**
     * @param array<string, mixed>|list<mixed>|null $details
     *
     * @return array{success: false, error: array{code: string, message: string, details?: mixed}, request_id: string}
     */
    public static function payload(
        int $httpStatus,
        string $message,
        ?string $errorCode = null,
        ?array $details = null,
        ?string $requestId = null,
    ): array {
        $rid = $requestId ?? RequestContext::requestId() ?? '';
        $code = $errorCode ?? self::defaultCodeForStatus($httpStatus);
        $error = [
            'code' => $code,
            'message' => $message,
        ];
        if ($details !== null && $details !== []) {
            $error['details'] = $details;
        }

        return [
            'success' => false,
            'error' => $error,
            'request_id' => $rid,
        ];
    }

    public static function defaultCodeForStatus(int $status): string
    {
        return match ($status) {
            400 => 'BAD_REQUEST',
            401 => 'UNAUTHORIZED',
            403 => 'FORBIDDEN',
            404 => 'NOT_FOUND',
            405 => 'METHOD_NOT_ALLOWED',
            409 => 'CONFLICT',
            415 => 'UNSUPPORTED_MEDIA_TYPE',
            422 => 'VALIDATION_ERROR',
            429 => 'TOO_MANY_REQUESTS',
            default => $status >= 500 ? 'INTERNAL_ERROR' : 'BAD_REQUEST',
        };
    }
}
