<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Models\User;
use App\Services\JwtService;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

trait ControllerTrait
{
    protected function success(Response $response, mixed $data, int $status = 200): Response
    {
        $response->getBody()->write(json_encode([
            'error' => false,
            'data'  => $data,
        ], JSON_UNESCAPED_UNICODE));

        return $response
            ->withHeader('Content-Type', 'application/json')
            ->withStatus($status);
    }

    protected function successList(Response $response, array $data, array $meta): Response
    {
        $response->getBody()->write(json_encode([
            'error' => false,
            'data'  => $data,
            'meta'  => $meta,
        ], JSON_UNESCAPED_UNICODE));

        return $response
            ->withHeader('Content-Type', 'application/json')
            ->withStatus(200);
    }

    protected function error(Response $response, string $code, string $message, int $status = 400): Response
    {
        $response->getBody()->write(json_encode([
            'error'   => true,
            'code'    => $code,
            'message' => $message,
        ], JSON_UNESCAPED_UNICODE));

        return $response
            ->withHeader('Content-Type', 'application/json')
            ->withStatus($status);
    }

    protected function getAuthUser(Request $request): ?User
    {
        $jwt  = new JwtService();
        return $jwt->getUserFromRequest($request);
    }

    protected function getAuthPayload(Request $request): ?object
    {
        $jwt = new JwtService();
        return $jwt->extractFromRequest($request);
    }

    protected function requireRole(Request $request, Response $response, array $roles): ?Response
    {
        $payload = $this->getAuthPayload($request);
        if (!$payload) {
            return $this->error($response, 'UNAUTHORIZED', 'Non authentifié', 401);
        }
        if (!in_array($payload->role, $roles, true)) {
            return $this->error($response, 'FORBIDDEN', 'Accès refusé', 403);
        }
        return null;
    }

    protected function paginate(Request $request): array
    {
        $params = $request->getQueryParams();
        $page   = max(1, (int)($params['page'] ?? 1));
        $limit  = min(100, max(1, (int)($params['limit'] ?? 20)));
        return [$page, $limit, ($page - 1) * $limit];
    }

    protected function logAudit(int $userId = null, string $action = '', string $entite = null, int $entiteId = null, array $details = [], Request $request = null): void
    {
        try {
            \Illuminate\Database\Capsule\Manager::table('logs_audit')->insert([
                'user_id'   => $userId,
                'action'    => $action,
                'entite'    => $entite,
                'entite_id' => $entiteId,
                'details'   => $details ? json_encode($details) : null,
                'ip'        => $request ? ($request->getServerParams()['REMOTE_ADDR'] ?? null) : null,
                'created_at'=> date('Y-m-d H:i:s'),
            ]);
        } catch (\Exception $e) {
            error_log('[ControllerTrait::logAudit] ' . $e->getMessage());
        }
    }
}
