<?php

namespace App\Controllers\Api;

use App\Controllers\BaseController;
use App\Libraries\ApiKeyManager;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;

abstract class BaseApiController extends BaseController
{
    protected ?array $apiKey = null;
    protected ApiKeyManager $apiKeys;

    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->apiKeys = new ApiKeyManager();
        $this->apiKey = $this->apiKeys->authenticateRequest($request);
    }

    protected function requireApiScope(string $scope)
    {
        if (! $this->apiKey) {
            return $this->failUnauthorized('Missing or invalid Bearer token.');
        }

        if (! $this->apiKeys->allows($this->apiKey, $scope)) {
            return $this->failForbidden('This API key does not have the required scope.');
        }

        return null;
    }

    protected function requireAnyApiScope(array $scopes)
    {
        if (! $this->apiKey) {
            return $this->failUnauthorized('Missing or invalid Bearer token.');
        }

        foreach ($scopes as $scope) {
            if ($this->apiKeys->allows($this->apiKey, $scope)) {
                return null;
            }
        }

        return $this->failForbidden('This API key does not have one of the required scopes.');
    }

    protected function apiOrganizationId(): int
    {
        return (int) ($this->apiKey['organization_id'] ?? 0);
    }

    protected function payload(): array
    {
        return $this->request->getJSON(true) ?: $this->request->getPost() ?: [];
    }

    protected function respondOk($data = null, int $statusCode = 200)
    {
        return $this->response->setStatusCode($statusCode)->setJSON([
            'status' => 'ok',
            'data' => $data,
        ]);
    }

    protected function failValidation(array $errors)
    {
        return $this->response->setStatusCode(422)->setJSON([
            'status' => 'error',
            'message' => 'Validation failed.',
            'errors' => $errors,
        ]);
    }

    protected function failUnauthorized(string $message)
    {
        return $this->response->setStatusCode(401)->setJSON([
            'status' => 'error',
            'message' => $message,
        ]);
    }

    protected function failForbidden(string $message)
    {
        return $this->response->setStatusCode(403)->setJSON([
            'status' => 'error',
            'message' => $message,
        ]);
    }

    protected function failNotFound(string $message)
    {
        return $this->response->setStatusCode(404)->setJSON([
            'status' => 'error',
            'message' => $message,
        ]);
    }
}
