<?php

/*
 * This file is part of the Serenity package.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Serenity\SaasBundle\Voter;

use Serenity\AuthBundle\Domain\User\Model\User;
use Serenity\CoreBundle\Shared\Common\UserInterface;
use Serenity\CoreBundle\Shared\Feature\SerenitySaasInterface;
use Serenity\SaasBundle\Entity\Tenant;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Vote;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;

class SaasIdentifierResourceAccessVoter extends Voter
{
    public const string VIEW = 'VIEW';
    public const string EDIT = 'EDIT';
    public const string DELETE = 'DELETE';

    public function __construct(
        #[Autowire(param: 'serenity_saas')]
        private readonly bool $serenitySaas,
    ) {
    }

    protected function supports(string $attribute, mixed $subject): bool
    {
        return \in_array($attribute, [self::EDIT, self::DELETE, self::VIEW], true)
          && $subject instanceof SerenitySaasInterface && $this->serenitySaas;
    }

    protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool
    {
        $user = $token->getUser();
        if (!$user instanceof UserInterface) {
            return false;
        }

        /** @var SerenitySaasInterface $resource */
        $resource = $subject;

        $saasIdentifier = $resource->getSaasIdentifier();

        // Cas 1 : aucun saas_identifier → seul les super admin
        if ($user instanceof User) {
            return \in_array('ROLE_SUPER_ADMIN', $user->getRoles(), true);
        }

        if ($saasIdentifier && $user instanceof Tenant) {
            // Cas 2 : il y a un saas_identifier → vérifier si le user appartient au tenant lié
            foreach ($user->getProjects() as $project) {
                if ($project->getIdentifier() === $saasIdentifier) {
                    return true;
                }
            }
        }

        return false;
    }
}
