<?php

namespace Myvetshop\Module\Clinique\Controller;

use Myvetshop\Module\Clinique\Accounting\Export\AccountingExporter;
use Myvetshop\Module\Clinique\Accounting\Export\PostProcess\RegroupByDayPostProcessor;
use Myvetshop\Module\Clinique\Form\Admin\Accounting\DownloadExportType;
use PrestaShop\PrestaShop\Core\Form\FormHandlerInterface;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use PrestaShopBundle\Security\Annotation\AdminSecurity;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;

class AccountingController extends FrameworkBundleAdminController
{
    private AccountingExporter $exporter;

    private FormFactoryInterface $formFactory;

    private FormHandlerInterface $exportFormHandler;

    private RegroupByDayPostProcessor $regroupByDayPostProcessor;

    /**
     * @param array{date_from?: string, date_to?: string, group_by_day?: bool|null} $formData
     *
     * @return FormInterface<array{date_from: string, date_to: string}>
     */
    protected function getDownloadForm(array $formData): FormInterface
    {
        return $this->formFactory
            ->create(
                DownloadExportType::class,
                $formData,
                [
                    'action' => $this->generateUrl('accounting_export_download'),
                ]
            );
    }

    public function __construct(
        AccountingExporter $exporter,
        FormFactoryInterface $formFactory,
        FormHandlerInterface $exportFormHandler,
        RegroupByDayPostProcessor $regroupByDayPostProcessor
    ) {
        $this->exporter = $exporter;
        $this->exportFormHandler = $exportFormHandler;
        $this->formFactory = $formFactory;
        $this->regroupByDayPostProcessor = $regroupByDayPostProcessor;

        parent::__construct();
    }

    /**
     * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))", message="You do not have permission to get accouting exports.")
     */
    public function exportAction(Request $request): ?Response
    {
        $form = $this->exportFormHandler->getForm();
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            /** @var array{date_from: string, date_to: string, 'group_by_day': bool|null} $data */
            $data = $form->getData();

            $startDate = \DateTimeImmutable::createFromFormat('Y-m-d', $data['date_from']);
            $endDate = \DateTimeImmutable::createFromFormat('Y-m-d', $data['date_to']);

            \assert($startDate instanceof \DateTimeImmutable);
            \assert($endDate instanceof \DateTimeImmutable);

            if ($data['group_by_day']) {
                $postProcessor = $this->regroupByDayPostProcessor;
            } else {
                $postProcessor = null;
            }

            $stats = $this->exporter->getStats($startDate, $endDate, $postProcessor);

            $downloadForm = $this->getDownloadForm(
                [
                    'date_from' => $startDate->format('Y-m-d'),
                    'date_to' => $endDate->format('Y-m-d'),
                    'group_by_day' => $data['group_by_day'],
                ]
            );
        } else {
            $stats = null;
            $startDate = null;
            $endDate = null;
            $downloadForm = null;
        }

        return $this->render(
            '@Modules/myvetshopclinique/templates/admin/accounting/export.html.twig',
            [
                'exportForm' => $form->createView(),
                'stats' => $stats,
                'startDate' => $startDate,
                'endDate' => $endDate,
                'downloadForm' => $downloadForm ? $downloadForm->createView() : null,
            ]
        );
    }

    /**
     * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))", message="You do not have permission to get accouting exports.")
     */
    public function downloadExportAction(Request $request): Response
    {
        $downloadForm = $this->getDownloadForm([]);
        $downloadForm->handleRequest($request);

        if (!$downloadForm->isSubmitted()) {
            throw new \Exception('Form not submitted');
        }

        /** @var array{date_from: string, date_to: string, group_by_day: bool|null} $data */
        $data = $downloadForm->getData();

        $startDate = \DateTimeImmutable::createFromFormat('Y-m-d', $data['date_from']);
        $endDate = \DateTimeImmutable::createFromFormat('Y-m-d', $data['date_to']);

        \assert($startDate instanceof \DateTimeImmutable);
        \assert($endDate instanceof \DateTimeImmutable);

        if ($data['group_by_day']) {
            $postProcessor = $this->regroupByDayPostProcessor;
        } else {
            $postProcessor = null;
        }

        $csv = $this->exporter->getCsv($startDate, $endDate, $postProcessor);
        $filename = 'export-comptable-'
            . $startDate->format('Y-m-d')
            . '-'
            . $endDate->format('Y-m-d')
            . '.csv';

        return new StreamedResponse(
            function () use ($csv) {
                fpassthru($csv);
                fclose($csv);
            },
            Response::HTTP_OK,
            [
                'Content-Type' => 'text/csv',
                'Content-Disposition' => 'attachment; filename="' . $filename . '"',
            ]
        );
    }
}
