<?php

namespace App\Clinic\Security;

use App\Auth\Entity\User;
use App\Clinic\Entity\Clinic;
use App\Clinic\Repository\ClinicDoctorPermissionRepository;
use App\Doctor\Repository\DoctorRepository;
use App\Shared\Constant\ErrorCodes;
use App\Shared\Exception\AppException;

/**
 * تصمیم‌گیرندهٔ واحد برای «این کاربر در این کلینیک اجازهٔ فلان کار را دارد؟».
 *
 * مالک کلینیک و ادمین همیشه مجازند — مالک هرگز نباید بتواند خودش را قفل کند.
 */
class ClinicDoctorPermissionChecker
{
    public function __construct(
        private readonly ClinicDoctorPermissionRepository $permRepo,
        private readonly DoctorRepository                 $doctorRepo,
    ) {}

    public function can(User $user, Clinic $clinic, string $resource, string $action): bool
    {
        if ($user->hasRole('ROLE_ADMIN') || $clinic->getUser()->getId() === $user->getId()) {
            return true;
        }

        $doctor = $this->doctorRepo->findByUser($user);
        if ($doctor === null || !$clinic->hasDoctor($doctor)) {
            return false;
        }

        return $this->permRepo->getOrCreate($clinic, $doctor)->can($resource, $action);
    }

    public function assert(User $user, Clinic $clinic, string $resource, string $action): void
    {
        if (!$this->can($user, $clinic, $resource, $action)) {
            throw new AppException(ErrorCodes::ERR_ACCESS_DENIED, 'دسترسی ندارید', 403);
        }
    }
}
