<?php

namespace ChurchCRM\Slim\Middleware\Request\Auth;

use ChurchCRM\Authentication\AuthenticationManager;
use ChurchCRM\Utils\LoggerUtils;
use Laminas\Diactoros\Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Psr\Http\Message\ResponseInterface;

class ManageGroupRoleAuthMiddleware extends BaseAuthRoleMiddleware
{
    protected function hasRole(): bool
    {
        return $this->user->isManageGroupsEnabled();
    }

    public function process(Request $request, RequestHandler $handler): ResponseInterface
    {
        try {
            $this->user = AuthenticationManager::getCurrentUser();
        } catch (\Throwable $ex) {
            $logger = LoggerUtils::getAppLogger();
            $logger->warning('User authentication failed in role middleware', [
                'path' => $request->getUri()->getPath(),
                'method' => $request->getMethod(),
                'exception' => $ex->getMessage()
            ]);

            if ($this->isBrowserRequest($request)) {
                return $this->redirectToAccessDenied('Authentication');
            }

            $response = new Response();
            $errorBody = json_encode(['error' => gettext('No logged in user'), 'code' => 401]);
            $response->getBody()->write($errorBody);
            return $response->withStatus(401)->withHeader('Content-Type', 'application/json');
        }

        if (!$this->hasRole()) {
            $method = strtoupper($request->getMethod());
            // Allow read-only methods (GET, HEAD) through — they are view-only operations.
            if (!in_array($method, ['GET', 'HEAD'], true)) {
                $route = $request->getAttribute('route');
                $groupId = $route ? $route->getArgument('groupID') : null;
                if ($groupId === null || !$this->user->isGroupLeaderFor((int)$groupId)) {
                    $logger = LoggerUtils::getAppLogger();
                    $logger->warning('User lacks required role', [
                        'path' => $request->getUri()->getPath(),
                        'method' => $request->getMethod(),
                        'user' => $this->user->getUserName(),
                        'required_role' => $this->noRoleMessage()
                    ]);

                    if ($this->isBrowserRequest($request)) {
                        return $this->redirectToAccessDenied($this->getRoleName());
                    }

                    $response = new Response();
                    $errorBody = json_encode(['error' => $this->noRoleMessage(), 'code' => 403]);
                    $response->getBody()->write($errorBody);
                    return $response->withStatus(403)->withHeader('Content-Type', 'application/json');
                }
            }
        }

        return $handler->handle($request);
    }

    protected function noRoleMessage(): string
    {
        return gettext('User must have Manage Groups permission');
    }

    protected function getRoleName(): string
    {
        return 'ManageGroups';
    }
}
