<?php

namespace Comitium5\DesignerBundle\Provider;

use Comitium5\ApiClientBundle\Client\Client;
use Comitium5\ApiClientBundle\Client\Services\UserApiService;
use Comitium5\DesignerBundle\Entity\User;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;

/**
 * Class BackEndUserLoginProvider
 *
 * @author Carles Gómez <carles@bab-soft.com>
 * @package Comitium5\DesignerBundle\Provider
 */
class BackEndUserLoginProvider implements UserProviderInterface
{
    private $apiClient;

    /**
     * BackEndUserLoginProvider constructor.
     *
     * @param Client $apiClient
     */
    public function __construct(Client $apiClient)
    {
        $this->apiClient = $apiClient;
    }

    /**
     * @param string $token
     *
     * @return UserInterface
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function loadUserByUsername($token)
    {
        $userData = $this->fetchByToken($token);

        return new User(
            $userData["id"],
            $userData["username"],
            $userData["subsites"],
            $userData['permissions'],
            $userData['name'] ?? '',
            $userData['surnames'] ?? '',
            $token
        );
    }

    /**
     * @param UserInterface $user
     *
     * @return UserInterface
     */
    public function refreshUser(UserInterface $user)
    {
        if ($this->supportsClass(get_class($user)) === false) {
            throw new UnsupportedUserException(
                sprintf('Instances of "%s" are not supported.', get_class($user))
            );
        }

        return $user;
    }

    /**
     * @param string $class
     *
     * @return bool
     */
    public function supportsClass($class)
    {
        return $class === User::class;
    }

    /**
     * @param string $token
     *
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    private function fetchByToken(string $token): array
    {
        $userApiService = new UserApiService($this->apiClient);

        $user = $userApiService->fetchByToken($token);

        if (empty($user)) {
            throw new UsernameNotFoundException(sprintf('Invalid token ("%s").', $token));
        }

        return $user;
    }

    /**
     * @param $site
     * @param $subsite
     * @param $locale
     */
    public function buildClient($site, $subsite, $locale)
    {
        $this
            ->apiClient
            ->buildClient($site, $subsite, $locale);
    }
}
