<?php

namespace Myvetshop\Module\Clinique\Adapter\Controller\Front;

use Myvetshop\Module\Clinique\Adapter\Controller\FrontControllerAdapterInterface;
use Myvetshop\Module\Clinique\Api\Crokit\CrokitApiClient;
use Myvetshop\Module\Clinique\Api\Crokit\RecommandationImporter;
use Myvetshop\Module\Clinique\Presenter\RecommandationPresenter;
use Myvetshop\Module\Clinique\Repository\AnimalRepository;
use Myvetshop\Module\Clinique\Repository\RecommandationRepository;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\OptionsResolver\OptionsResolver;

class MyRecoImportControllerAdapter implements FrontControllerAdapterInterface
{
    private AnimalRepository $animalRepository;

    private CrokitApiClient $crokitApiClient;

    private RecommandationImporter $recommandationImporter;

    private RecommandationPresenter $recommandationPresenter;

    private RecommandationRepository $recommandationRepository;

    public function __construct(
        AnimalRepository $animalRepository,
        CrokitApiClient $crokitApiClient,
        RecommandationImporter $recommandationImporter,
        RecommandationPresenter $recommandationPresenter,
        RecommandationRepository $recommandationRepository
    ) {
        $this->animalRepository = $animalRepository;
        $this->crokitApiClient = $crokitApiClient;
        $this->recommandationImporter = $recommandationImporter;
        $this->recommandationPresenter = $recommandationPresenter;
        $this->recommandationRepository = $recommandationRepository;
    }

    /**
     * @param \Context $context
     * @param Request $request
     *
     * @return array{template: string, parameters: array<mixed>, errors?: string[], success?: string[], redirect?: string}
     */
    public function handleRequest(
        \Context $context,
        Request $request
    ): array {
        try {
            $recommandations = $this->recommandationRepository
                ->findBy(['idCustomer' => $context->customer->id, 'deleted' => false]);
            $animals = $this->animalRepository->findBy([
                'idCustomer' => (int) $context->customer->id,
                'deleted' => false,
            ]);
        } catch (\Exception $e) {
            return [
                'template' => 'module:myvetshopclinique/views/templates/front/myreco/recommandations.tpl',
                'parameters' => [
                    'animals' => [],
                    'code' => null,
                    'recommandations' => [],
                ],
                'errors' => [
                    $e->getMessage(),
                ],
            ];
        }

        try {
            $optionResolver = new OptionsResolver();
            $optionResolver->setDefaults([
                'code' => null,
                'id_animal' => null,
            ]);
            $optionResolver->setAllowedTypes('code', ['string', 'null']);
            $optionResolver->setAllowedTypes('id_animal', ['string', 'null']);
            $optionResolver->setDefined(
                \array_keys(
                    \array_merge(
                        $request->query->all(),
                        $request->request->all()
                    )
                )
            );

            /* @var array{code: string|null, id_animal: string|null} $queryParams */
            $queryParams = $optionResolver->resolve(
                \array_merge(
                    $request->query->all(),
                    $request->request->all()
                )
            );

            $codeReco = $queryParams['code'];

            if (null === $codeReco) {
                return [
                    'template' => 'module:myvetshopclinique/views/templates/front/myreco/recommandations.tpl',
                    'parameters' => [
                        'animals' => $animals,
                        'code' => null,
                        'recommandations' => \array_map([$this->recommandationPresenter, 'present'], $recommandations),
                    ],
                ];
            }

            $recommandation = $this->crokitApiClient->getRecommandation($codeReco);

            if (null !== $recommandation) {
                $recoEnBase = $this->recommandationRepository->findOneBy(['codeReco' => $codeReco, 'deleted' => false]);

                if ($recoEnBase) {
                    return [
                        'template' => 'module:myvetshopclinique/views/templates/front/myreco/recommandations.tpl',
                        'parameters' => [
                            'animals' => $animals,
                            'code' => $codeReco,
                            'recommandations' => \array_map([$this->recommandationPresenter, 'present'], $recommandations),
                        ],
                        'errors' => [
                            'Le code fourni a déjà été importé',
                        ],
                    ];
                }
            } else {
                return [
                    'template' => 'module:myvetshopclinique/views/templates/front/myreco/recommandations.tpl',
                    'parameters' => [
                        'animals' => $animals,
                        'code' => $codeReco,
                        'recommandations' => \array_map([$this->recommandationPresenter, 'present'], $recommandations),
                    ],
                    'errors' => [
                        'Le code recommandation n\'existe pas',
                    ],
                ];
            }

            // Si la recommandation existe, mais que l'utilisateur n'est pas connecté, on lui demande de se connecter
            if (!$context->customer->id) {
                return [
                    'template' => 'module:myvetshopclinique/views/templates/front/myreco/recommandation_public.tpl',
                    'parameters' => [
                        'animals' => $animals,
                        'code' => $codeReco,
                        'recommandation' => $this->recommandationPresenter->presentDto($recommandation),
                        'recommandations' => \array_map([$this->recommandationPresenter, 'present'], $recommandations),
                    ],
                ];
            }

            $idAnimal = $queryParams['id_animal'];

            if (null === $idAnimal) {
                // Sélection de l'animal pour import
                return [
                    'template' => 'module:myvetshopclinique/views/templates/front/myreco/recommandations.tpl',
                    'parameters' => [
                        'animals' => $animals,
                        'code' => $codeReco,
                        'recommandation' => $this->recommandationPresenter->presentDto($recommandation),
                        'recommandations' => \array_map([$this->recommandationPresenter, 'present'], $recommandations),
                    ],
                ];
            }

            // Création de la recommandation (et de l'animal au besoin) en base de données
            $animal = $this->recommandationImporter->getRecommandationAnimal(
                \strval($idAnimal),
                $context->customer,
                $recommandation
            );
            $recoEnBase = $this->recommandationImporter->import($recommandation, $animal);

            // Ajoute la recommandation à la liste
            $recommandations[] = $recoEnBase;
            if (!\in_array($animal, $animals)) {
                $animals[] = $animal;
            }
        } catch (\Exception $e) {
            return [
                'template' => 'module:myvetshopclinique/views/templates/front/myreco/recommandations.tpl',
                'parameters' => [
                    'animals' => $animals,
                    'code' => null,
                    'recommandations' => \array_map([$this->recommandationPresenter, 'present'], $recommandations),
                ],
                'errors' => [
                    $e->getMessage(),
                ],
            ];
        }

        return [
            'template' => 'module:myvetshopclinique/views/templates/front/myreco/recommandations.tpl',
            'parameters' => [
                'animals' => $animals,
                'code' => null,
                'recommandations' => \array_map([$this->recommandationPresenter, 'present'], $recommandations),
            ],
            'success' => [
                'Recommandation importée',
            ],
        ];
    }
}
