<?php

namespace App\Controller\Admin;

use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Security\Core\Security;

/**
 * Class UserCrudController
 * @package App\Controller\Admin
 */
class UserCrudController extends AbstractCrudController
{
	private ?string $password;
	
	public static function getEntityFqcn(): string
	{
		return User::class;
	}
	
	/**
	 * @var UserPasswordHasherInterface
	 */
	private UserPasswordHasherInterface $passwordHasher;
	/**
	 * @var Security
	 */
	private Security $security;
	
	/**
	 * UserCrudController constructor.
	 *
	 * @param \Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface $passwordHasher
	 * @param Security                                                             $security
	 */
	public function __construct(UserPasswordHasherInterface $passwordHasher, Security $security)
	{
		$this->passwordHasher = $passwordHasher;
		$this->security = $security;
		
		// get the user id from the logged in user
		if (null !== $this->security->getUser()) {
			$this->password = $this->security->getUser()->getPassword();
		}
	}
	
	public function configureActions(Actions $actions): Actions
	{
		return $actions
			->add(Crud::PAGE_INDEX, Crud::PAGE_DETAIL);
	}
	
	
	/**
	 * @param string $pageName
	 *
	 * @return iterable
	 */
	public function configureFields(string $pageName): iterable
	{
		$username = TextField::new('username');
		$email = TextField::new('email');
		$firstName = TextField::new('firstName');
		$lastName = TextField::new('lastName');
		$createdAt = DateTimeField::new('createdAt');
		$lastLoginAt = DateTimeField::new('lastLoginAt');
		$isVerified = BooleanField::new('isVerified');
		$roles = ChoiceField::new('roles', 'Roles')
			->allowMultipleChoices()
			->autocomplete()
			->setChoices([
					'User'       => 'ROLE_USER',
					'Admin'      => 'ROLE_ADMIN',
					'SuperAdmin' => 'ROLE_SUPER_ADMIN']
			);
		$password = TextField::new('password')
			->setFormType(PasswordType::class)
			->setFormTypeOption('empty_data', '')
			->setRequired(false)
			->setHelp('Leave blank to keep the current password');
		
		switch ($pageName) {
			case Crud::PAGE_INDEX:
				return [$username, $firstName, $lastName, $email, $lastLoginAt];
			case Crud::PAGE_DETAIL:
				return [$username, $firstName, $lastName, $email, $lastLoginAt, $createdAt, $roles, $isVerified];
			case Crud::PAGE_NEW:
				return [
					$password,
				];
			case Crud::PAGE_EDIT:
				return [$username, $password, $firstName, $lastName, $email, $lastLoginAt, $roles, $isVerified];
			
		}
		return [];
	}
	
	/**
	 *
	 * @param EntityManagerInterface $entityManager
	 * @param                        $entityInstance
	 */
	public function updateEntity(EntityManagerInterface $entityManager, $entityInstance): void
	{
		// set new password with hash interface
		if (method_exists($entityInstance, 'setPassword')) {
			$plainPassword = trim($this->get('request_stack')->getCurrentRequest()->request->all('User')['password']);
			
			// do nothing if no password is entered
			if (isset($plainPassword) === true && $plainPassword === '') {
				$entityInstance->setPassword($this->password);
			} else {
				$user = new User();
				$hashedPassword = $this->passwordHasher->hashPassword($user, $plainPassword);
				$entityInstance->setPassword($hashedPassword);
			}
		}
		
		parent::updateEntity($entityManager, $entityInstance);
	}
}
