<?php

namespace App\Controller;

use App\DataTransferObject\CompanyDetailsDto;
use App\Entity\User;
use App\Enums\CaseLevel;
use App\Enums\JobType;
use App\Enums\RateType;
use App\Factory\CompanyFactory;
use App\Form\CompanyFormType;
use App\Form\RegistrationFormType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;

class RegistrationController extends AbstractController
{
    public const REGISTER_STEP_ONE = 'admin';
    public const REGISTER_STEP_TWO = 'company';

    public function __construct(
        private readonly CompanyFactory $companyFactory,
        private readonly RequestStack $requestStack,
        private readonly EntityManagerInterface $entityManager,
        private readonly UserPasswordHasherInterface $userPasswordHasher,
        private readonly UserAuthenticatorInterface $userAuthenticator
    ) {

    }

    #[Route('/register/{step}', name: 'app_register_step')]
    public function registerStep(string $step, Request $request, #[CurrentUser] ?User $user): Response
    {
        $form = match($step) {
            self::REGISTER_STEP_ONE => $this->createForm(RegistrationFormType::class),
            self::REGISTER_STEP_TWO => $this->renderRegisterStepTwo(),
            default => $this->redirectToRoute('app_register_step', ['step' => self::REGISTER_STEP_ONE]),
        };

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            return match(true) {
                $step === self::REGISTER_STEP_ONE => $this->handleRegisterStepOne($form, $request),
                $step === self::REGISTER_STEP_TWO => $this->handleRegisterStepTwo($form, $user),
                default => $this->redirectToRoute('app_register_step', ['step' => self::REGISTER_STEP_ONE]),
            };
        }

        return $this->render(sprintf('registration/register-step-%s.html.twig', $step), [
            'form' => $form,
            'data' => $form->getData(),
            'admin' => $user
        ]);
    }

    private function handleRegisterStepOne(FormInterface $form, Request $request): Response
    {
        $user = new User();
        $form = $this->createForm(RegistrationFormType::class, $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            /** @var string $plainPassword */
            $plainPassword = $form->get('plainPassword')->getData();

            // encode the plain password
            $user->setPassword(
                $this->userPasswordHasher->hashPassword(
                    $user,
                    $plainPassword
                )
            );

            $user->setCaseWorker(true)
                 ->setCaseManager(true)
                 ->setTherapist(true)
                 ->setSu(true)
                 ->setRateType(RateType::FIXED)
                 ->setRate('0.00')
                 ->setRoles(['ROLE_ADMIN'])
                 ->setLevel(CaseLevel::ADMIN);

            // save user
            $this->entityManager->persist($user);
            $this->entityManager->flush();

            return $this->redirectToRoute('app_dashboard');
        }

        return $this->redirectToRoute('app_register_step', ['step' => self::REGISTER_STEP_ONE]);
    }

    private function renderRegisterStepTwo(): FormInterface
    {
        $company = $this->requestStack->getSession()->get('register-form-step-two');

        if (!$company instanceof CompanyDetailsDto) {
            $company = new CompanyDetailsDto();
        }

        return $this->createForm(CompanyFormType::class, $company);
    }

    private function handleRegisterStepTwo(FormInterface $form, User $owner): Response
    {
        $company = $this->companyFactory->create($form->getData(), $owner);

        $owner->setCompany($company);
        $this->entityManager->persist($owner);
        $this->entityManager->persist($company);
        $this->entityManager->flush();

        return $this->redirectToRoute('app_dashboard');
    }

    #[Route('/register', name: 'app_register')]
    public function register(): Response
    {
        return $this->redirectToRoute('app_register_step', ['step' => self::REGISTER_STEP_ONE]);
    }

}
