<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\PersonBundle\Security\Authorization;

use Chill\MainBundle\Security\Authorization\ChillVoterInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;

class AccompanyingPeriodWorkEvaluationVoter extends Voter implements ChillVoterInterface
{
    final public const ALL = [
        self::SEE,
        self::SEE_AND_EDIT,
        self::STATS,
    ];

    final public const SEE = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_SHOW';

    final public const SEE_AND_EDIT = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_EDIT';

    final public const STATS = 'CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_EVALUATION_STATS';

    public function __construct(private readonly Security $security) {}

    protected function supports($attribute, $subject)
    {
        return $subject instanceof AccompanyingPeriodWorkEvaluation
            && \in_array($attribute, self::ALL, true);
    }

    /**
     * @param string                           $attribute
     * @param AccompanyingPeriodWorkEvaluation $subject
     */
    protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
    {
        return match ($attribute) {
            self::STATS => $this->security->isGranted(AccompanyingPeriodVoter::STATS, $subject),
            self::SEE => $this->security->isGranted(AccompanyingPeriodWorkVoter::SEE, $subject->getAccompanyingPeriodWork()),
            self::SEE_AND_EDIT => $this->security->isGranted(AccompanyingPeriodWorkVoter::UPDATE, $subject->getAccompanyingPeriodWork()),
            default => throw new \UnexpectedValueException("attribute {$attribute} is not supported"),
        };
    }
}
