<?php

namespace AutoAdmin\Bundle\Admin\Controller\Admin;

use AutoAdmin\Bundle\Admin\Form\ImportRedirectType;
use AutoAdmin\Bundle\Admin\Helper\FlashbagHelper;
use AutoAdmin\Bundle\Seo\Entity\Redirect;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;

class RedirectController extends EntityController
{
    private const ERROR_FILENAME = 'erreurs-import.csv';

    private string $projectDir;

    public function __construct(
        private readonly EntityManagerInterface $entityManager,
        private readonly ValidatorInterface $validator,
        KernelInterface $kernel
    )
    {
        $this->projectDir = $kernel->getProjectDir();
        parent::__construct();
    }

    public function import(string $entitySlug, Request $request): RedirectResponse|Response
    {
        $this->ensureActionIsAllowed($entitySlug, 'import');
        
        $form = $this->createForm(ImportRedirectType::class, null, [
            'help' => $this->adminRouter->generate($entitySlug, 'templateFile'),
        ]);
        
        $form->handleRequest($request);

        $importErrors = [];

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

            if ($file) {
                foreach (explode("\n", $file->getContent()) as $key => $row) {
                    $data = explode(";", $row);

                    if (($key === 0 && $form->get('skip_first_line')->getData()) || count($data) !== 3) {
                        continue;
                    }

                    $class = $this->entityHelper->findFullClassName($entitySlug);
                    /** @var Redirect $entity */
                    $redirect = $this->contentFactory->createEntity($class);

                    $redirect->setOrigin($data[0]);
                    $redirect->setDestination($data[1]);
                    $redirect->setType((int)$data[2]);

                    $errors = $this->validator->validate($redirect);
                    
                    if (count($errors) > 0) {
                        $importErrors['data'][] = $data;
                        $importErrors['errors'][] = $errors;
                    } else {
                        $this->entityManager->persist($redirect);
                    }
                }

                $this->entityManager->flush();

                if (count($importErrors) > 0) {
                    FlashbagHelper::addWarning($request, "Redirections partiellement importées : <a href='{$this->generateErrorFile($importErrors)}' style='text-decoration: underline'>voir les erreurs</a>");
                } else {
                    FlashbagHelper::addSuccess($request, 'Import des redirections terminé');
                }

                return $this->redirectToRoute('aa_admin_entity', [
                    'entitySlug' => $entitySlug,
                    'action' => 'list',
                ]);
            }
        }

        return $this->render(
            '@AutoAdminAdmin/redirect/import.html.twig',
            [
                'form' => $form->createView(),
            ]
        );
    }

    public function templateFile(): BinaryFileResponse
    {
        $response = new BinaryFileResponse(__DIR__ . '/../../Resources/documents/redirect-import-template.csv');
        $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'fichier-exemple.csv');
        return $response;
    }

    private function generateErrorFile($errors): string
    {
        $filePath = $this->projectDir . '/var/files/' . self::ERROR_FILENAME;

        if (!is_dir(dirname($filePath))) {
            mkdir(dirname($filePath), 0755, true);
        }

        $handle = fopen($filePath, 'w');
        if ($handle) {
            fputcsv($handle, ['url_origine', 'url_destination', 'code_redirection'], ';');
            foreach ($errors['data'] as $datum) {
                fputcsv($handle, array_merge($datum), ';');
            }
            fclose($handle);
        }

        return $this->generateUrl('aa_admin_redirect_error_file_download');
    }

    public function downloadErrorFile(): BinaryFileResponse
    {
        $filePath = $this->projectDir . '/var/files/' . self::ERROR_FILENAME;

        $response = new BinaryFileResponse($filePath);
        $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, self::ERROR_FILENAME);

        $response->deleteFileAfterSend();

        return $response;
    }
}
