<?php

declare(strict_types=1);

namespace OCA\Mitgliederverwaltung\Controller;

use OCA\Mitgliederverwaltung\Service\PermissionService;
use OCP\AppFramework\ApiController;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;
use OCP\IUserManager;
use OCP\IUserSession;
use Psr\Log\LoggerInterface;

/**
 * REST API controller for permission management.
 *
 * Part of Issue #37.
 */
class PermissionController extends ApiController {

    use ApiControllerTrait;

    private PermissionService $permissionService;
    private IUserManager $userManager;
    private IUserSession $userSession;
    private LoggerInterface $logger;

    public function __construct(
        string $appName,
        IRequest $request,
        PermissionService $permissionService,
        IUserManager $userManager,
        IUserSession $userSession,
        LoggerInterface $logger
    ) {
        parent::__construct($appName, $request);
        $this->permissionService = $permissionService;
        $this->userManager = $userManager;
        $this->userSession = $userSession;
        $this->logger = $logger;
    }

    #[NoCSRFRequired]
    public function index(): JSONResponse {
        return $this->handleAction(function () {
            $permissions = $this->permissionService->getAllPermissions();
            return new JSONResponse(array_map(fn($p) => $p->jsonSerialize(), $permissions));
        }, 'Berechtigungen auflisten');
    }

    #[NoCSRFRequired]
    public function listUsers(): JSONResponse {
        return $this->handleAction(function () {
            $users = [];
            $this->userManager->callForAllUsers(function ($user) use (&$users) {
                $users[] = [
                    'uid' => $user->getUID(),
                    'displayName' => $user->getDisplayName(),
                ];
            });
            return new JSONResponse($users);
        }, 'Benutzer auflisten');
    }

    public function setPermission(string $ncUserId): JSONResponse {
        return $this->handleAction(function () use ($ncUserId) {
            $currentUser = $this->userSession->getUser();
            $currentUserId = $currentUser ? $currentUser->getUID() : null;

            $data = $this->getRequestData();
            $level = $data['level'] ?? 'none';

            if ($currentUserId === $ncUserId && $level !== 'admin') {
                $currentPerm = $this->permissionService->getUserPermission($ncUserId);
                if ($currentPerm !== null && $currentPerm->getLevel() === 'admin') {
                    return new JSONResponse(
                        ['error' => 'Eigene Admin-Berechtigung kann nicht entfernt werden.'],
                        Http::STATUS_BAD_REQUEST
                    );
                }
            }

            $perm = $this->permissionService->setPermission(
                $ncUserId,
                $level,
                $data['allowedStufen'] ?? null,
                (bool)($data['canSeeBanking'] ?? false)
            );

            return new JSONResponse($perm);
        }, 'Berechtigung setzen');
    }

    public function removePermission(string $ncUserId): JSONResponse {
        return $this->handleAction(function () use ($ncUserId) {
            $currentUser = $this->userSession->getUser();
            $currentUserId = $currentUser ? $currentUser->getUID() : null;

            if ($currentUserId === $ncUserId) {
                return new JSONResponse(
                    ['error' => 'Eigene Berechtigung kann nicht entfernt werden.'],
                    Http::STATUS_BAD_REQUEST
                );
            }

            $this->permissionService->removePermission($ncUserId);
            return new JSONResponse(['status' => 'removed']);
        }, 'Berechtigung entfernen');
    }
}
