<?php

namespace AutoAdmin\Bundle\Admin\Security\Voter;

use AutoAdmin\Bundle\Admin\Helper\AccessHelper;
use Exception;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;

/**
 * Should this class be removed/kept ???
 */
class AdminAccessVoter extends Voter
{
    private const PUBLIC_ADMIN_ROUTES = [
        'aa_admin_login',
        'aa_admin_logout',
        'aa_admin_password_reset_request',
        'aa_admin_password_reset_change',
    ];

    private AccessHelper $accessHelper;

    public function __construct(AccessHelper $accessHelper)
    {
        $this->accessHelper = $accessHelper;
    }

    /**
     * @throws Exception
     */
    public function vote(TokenInterface $token, mixed $subject, array $attributes): int
    {
        return self::ACCESS_ABSTAIN;
        /**
         * Super Admin has full access without exception.
         */
        //        if (in_array('ROLE_SUPER_ADMIN', $attributes)) {
        //            return self::ACCESS_GRANTED;
        //        }

        /**
         * If $subject is a Request
         */
        if ($subject instanceof Request) {
            return $this->voteOnRequest($token, $subject, $attributes);
        }

        /**
         * If this case is reach ... dump attributes and implement that shit :)
         */
        return self::ACCESS_DENIED;
    }

    /**
     * @throws Exception
     */
    private function voteOnRequest(TokenInterface $token, Request $request, array $attributes): int
    {
        if (in_array($request->attributes->get('_route'), self::PUBLIC_ADMIN_ROUTES)) {
            return self::ACCESS_GRANTED;
        }

        if (strpos($request->getRequestUri(), '/admin') !== 0) {
            return self::ACCESS_ABSTAIN;
        }

        $roleList = $this->accessHelper->getRoleListForRequest($request);

        return $this->accessHelper->voteOnRolesArray($roleList, $attributes);
    }

    protected function supports(string $attribute, mixed $subject): bool
    {
        return true;
    }

    protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
    {
        return false;
    }
}
