<?php

namespace Jotunheimr\UserBundle\Security\Core\User;

use Doctrine\ORM\EntityManager;
use FOS\UserBundle\Model\UserManagerInterface;
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
use HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider as BaseFOSUBProvider;
use Jotunheimr\UserBundle\Entity\User;
use Symfony\Component\Security\Core\User\UserInterface;

class MyFOSUBUserProvider extends BaseFOSUBProvider
{
    /** @var EntityManager */
    private $em;

    public function __construct(UserManagerInterface $userManager, array $properties, EntityManager $em)
    {
        parent::__construct($userManager, $properties);
        $this->em = $em;
    }

    /**
     * {@inheritDoc}
     */
    public function connect(UserInterface $user, UserResponseInterface $response)
    {
        $property = $this->getProperty($response);
        $username = $response->getUsername();

        $existingUser = $this->userManager->findUserBy(array($property => $username));

        if (null !== $existingUser) {
            $this->userManager->updateUser($existingUser);
        }

        $this->userManager->updateUser($user);
    }

    /**
     * {@inheritdoc}
     */
    public function loadUserByOAuthUserResponse(UserResponseInterface $response)
    {
        $userEmail = $response->getEmail();
        $user = $this->userManager->findUserByEmail($userEmail);

        if (null === $user) {
            $this->createUser($user, $response);
            return $user;
        } else {
            $this->createUser($user, $response);
        }

        $serviceName = $response->getResourceOwner()->getName();
        $setter = 'set' . ucfirst($serviceName) . 'AccessToken';
        $user->$setter($response->getAccessToken());

        return $user;
    }

    /**
     * @param $user
     * @param $response
     */
    private function createUser($user, $response)
    {
        $empty = null === $user;

        if ($empty) {
            $user = new User();
        }

        $user->setFacebookId($response->getUsername());
        $user->setEmail($response->getEmail());
        $user->setEmailCanonical($response->getEmail());
        $user->setUsername($this->slug($response->getRealName()));
        $user->setUsernameCanonical($this->slug($response->getRealName()));
        $user->setRealName($response->getRealName());
        $user->setNickName($response->getNickname());
        if ($empty) {
            $user->setPassword('social-user');
        }
        $user->setEnabled(true);

        $this->em->persist($user);
        $this->em->flush();
    }

    /**
     * @param $string
     * @return string
     */
    private function slug($string)
    {
        return strtolower(trim(preg_replace('~[^0-9a-z]+~i', '-', html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8')), ENT_QUOTES, 'UTF-8')), '-'));
    }
}
