<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\PersonBundle\Controller;

use Chill\PersonBundle\Entity\Person\PersonResource;
use Chill\PersonBundle\Form\PersonResourceType;
use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Repository\PersonResourceRepository;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\Translation\TranslatorInterface;

final class PersonResourceController extends AbstractController
{
    public function __construct(private readonly PersonResourceRepository $personResourceRepository, private readonly PersonRepository $personRepository, private readonly EntityManagerInterface $em, private readonly TranslatorInterface $translator) {}

    #[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/person/{person_id}/resources/{resource_id}/delete', name: 'chill_person_resource_delete')]
    public function deleteAction(Request $request, mixed $person_id, mixed $resource_id): Response
    {
        $personOwner = $this->personRepository->find($person_id);
        $resource = $this->personResourceRepository->find($resource_id);

        $this->denyAccessUnlessGranted(PersonVoter::UPDATE, $personOwner);

        if (null === $resource) {
            throw $this->createNotFoundException('Unable to find Resource entity.');
        }

        $form = $this->createFormBuilder()
            ->setAction($this->generateUrl('chill_person_resource_delete', [
                'resource_id' => $resource_id,
                'person_id' => $person_id,
            ]))
            ->add('submit', SubmitType::class, ['label' => 'Delete'])
            ->getForm();

        if (Request::METHOD_POST === $request->getMethod()) {
            $form->handleRequest($request);

            if ($form->isSubmitted() && $form->isValid()) {
                $this->em->remove($resource);
                $this->em->flush();

                $this->addFlash('success', $this->translator
                    ->trans('The resource has been successfully removed.'));

                return $this->redirectToRoute('chill_person_resource_list', [
                    'person_id' => $personOwner->getId(),
                ]);
            }
        }

        return $this->render(
            '@ChillPerson/PersonResource/delete.html.twig',
            [
                'person' => $personOwner,
                'resource' => $resource,
                'form' => $form->createView(),
            ]
        );
    }

    #[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/person/{person_id}/resources/{resource_id}/edit', name: 'chill_person_resource_edit')]
    public function editAction(Request $request, mixed $resource_id, mixed $person_id): Response
    {
        $resource = $this->personResourceRepository->find($resource_id);
        $personOwner = $this->personRepository->find($person_id);

        $this->denyAccessUnlessGranted(PersonVoter::UPDATE, $personOwner);

        if (null === $resource) {
            throw $this->createNotFoundException('Unable to find Resource entity.');
        }

        $form = $this->createForm(PersonResourceType::class, $resource);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $this->em->persist($resource);
            $this->em->flush();

            return $this->redirectToRoute('chill_person_resource_list', [
                'person_id' => $personOwner->getId(),
            ]);
        }

        return $this->render(
            '@ChillPerson/PersonResource/edit.html.twig',
            [
                'person' => $personOwner,
                'resource' => $resource,
                'form' => $form->createView(),
                'action' => 'edit',
            ]
        );
    }

    #[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/person/{person_id}/resources/list', name: 'chill_person_resource_list')]
    public function listAction(Request $request, mixed $person_id)
    {
        $personOwner = $this->personRepository->find($person_id);
        $this->denyAccessUnlessGranted(PersonVoter::SEE, $personOwner);

        $personResources = [];
        $personResources = $this->personResourceRepository->findBy(['personOwner' => $personOwner->getId()]);

        return $this->render(
            '@ChillPerson/PersonResource/list.html.twig',
            [
                'person' => $personOwner,
                'personResources' => $personResources,
            ]
        );
    }

    #[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/person/{person_id}/resources/new', name: 'chill_person_resource_new')]
    public function newAction(Request $request, mixed $person_id)
    {
        $personOwner = $this->personRepository->find($person_id);
        $personResource = new PersonResource();
        $personResource->setPersonOwner($personOwner);

        $form = $this->createForm(PersonResourceType::class, $personResource);

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $this->denyAccessUnlessGranted(PersonVoter::CREATE, $personOwner);

            $this->em->persist($personResource);
            $this->em->flush();

            return $this->redirectToRoute('chill_person_resource_list', [
                'person_id' => $personOwner->getId(),
            ]);
        }

        return $this->render(
            '@ChillPerson/PersonResource/create.html.twig',
            [
                'form' => $form->createView(),
                'person' => $personOwner,
            ]
        );
    }
}
