<?php
declare(strict_types=1);

namespace App\Core;

use App\Core\Exceptions\ValidationException;

abstract class ApiController extends Controller
{
    protected function successResponse($data, int $status = 200, array $meta = []): Response
    {
        return $this->json([
            'success' => true,
            'data' => $data,
            'meta' => $meta ?: null,
            'errors' => null,
        ], $status);
    }

    protected function errorResponse(string $message, int $status = 400, array $details = [], ?string $code = null): Response
    {
        return $this->json([
            'success' => false,
            'data' => null,
            'meta' => null,
            'errors' => [
                'code' => $code,
                'message' => $message,
                'details' => $details ?: null,
            ],
        ], $status);
    }

    protected function paginatedResponse(array $items, int $total, int $page, int $perPage): Response
    {
        return $this->json([
            'success' => true,
            'data' => $items,
            'meta' => [
                'total' => $total,
                'page' => $page,
                'per_page' => $perPage,
                'last_page' => (int) ceil($total / max($perPage, 1)),
            ],
            'errors' => null,
        ]);
    }

    protected function validatedJson(array $rules): array
    {
        $request = $this->getRequest();
        $input = $request->jsonBody();

        $validator = new Validator();
        $result = $validator->validate($input, $rules);

        if ($result->fails()) {
            throw new ValidationException($result->errors());
        }

        return $result->validated();
    }

    protected function getRequest(): Request
    {
        return $this->request;
    }

    protected function queryParam(string $key, $default = null)
    {
        return $this->request->get($key, $default);
    }

    protected function queryInt(string $key, int $default = 0): int
    {
        return (int) ($this->request->get($key) ?? $default);
    }
}
