<?php

namespace App\Controller;

use App\Controller\Trait\AccountEventOwnershipTrait;
use App\Entity\Attestation;
use App\Entity\Billet;
use App\Entity\BilletBuyer;
use App\Entity\BilletBuyerItem;
use App\Entity\BilletOrder;
use App\Entity\Category;
use App\Entity\Event;
use App\Entity\Payout;
use App\Entity\User;
use App\Service\AuditService;
use App\Service\BilletOrderService;
use App\Service\ExportService;
use App\Service\PayoutPdfService;
use App\Service\StripeService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted('ROLE_USER')]
class AccountEventOperationsController extends AbstractController
{
    use AccountEventOwnershipTrait;

    private const DQL_BB_EXCLUDE_INVITATIONS = 'bb.isInvitation = false OR bb.isInvitation IS NULL';
    private const CONTENT_TYPE_PDF = 'application/pdf';
    private const PDF_SUFFIX = '.pdf"';

    #[Route('/mon-compte/evenement/{id}/invitation', name: 'app_account_event_create_invitation', methods: ['POST'])]
    public function createInvitation(Event $event, Request $request, EntityManagerInterface $em, BilletOrderService $billetOrderService): Response
    {
        $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
        if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
            return $redirect;
        } // @codeCoverageIgnoreEnd

        $this->requireEventOwnership($event);

        $result = $this->buildInvitationOrder($event, $request, $em);

        if ($result instanceof Response) {
            return $result;
        }

        $order = $result;
        $em->persist($order);
        $em->flush();

        $billetOrderService->generateOrderTickets($order);

        $tickets = $em->getRepository(BilletOrder::class)->findBy(['billetBuyer' => $order]);
        foreach ($tickets as $ticket) {
            $ticket->setIsInvitation(true);
        }
        $em->flush();

        $billetOrderService->generateAndSendTickets($order);

        $this->addFlash('success', 'Invitation envoyee a '.$order->getEmail().'.');

        return $this->redirectToRoute('app_account_edit_event', ['id' => $event->getId(), 'tab' => 'invitations']);
    }

    #[Route('/mon-compte/evenement/{id}/accreditation', name: 'app_account_event_create_accreditation', methods: ['POST'])]
    public function createAccreditation(Event $event, Request $request, EntityManagerInterface $em, BilletOrderService $billetOrderService): Response
    {
        $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
        if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
            return $redirect;
        } // @codeCoverageIgnoreEnd

        $this->requireEventOwnership($event);

        $accreditationType = $request->request->getString('accreditation_type', 'staff');
        if (!\in_array($accreditationType, ['staff', 'exposant'], true)) {
            $accreditationType = 'staff';
        }

        $firstName = trim($request->request->getString('first_name'));
        $lastName = trim($request->request->getString('last_name'));
        $email = trim($request->request->getString('email'));
        $redirectResponse = $this->redirectToRoute('app_account_edit_event', ['id' => $event->getId(), 'tab' => 'invitations']);
        $categories = $em->getRepository(Category::class)->findBy(['event' => $event], ['position' => 'ASC']);

        $missingFields = '' === $firstName || '' === $lastName || '' === $email;
        if ($missingFields || empty($categories)) {
            $this->addFlash('error', $missingFields ? 'Tous les champs sont requis.' : 'Creez au moins une categorie avant de generer une accreditation.');

            return $redirectResponse;
        }

        $category = $categories[0];
        $label = 'staff' === $accreditationType ? 'Staff' : 'Exposant';

        $billet = new Billet();
        $billet->setCategory($category);
        $billet->setName($label.' - '.$firstName.' '.$lastName);
        $billet->setType($accreditationType);
        $billet->setPriceHT(0);
        $billet->setQuantity(1);
        $billet->setIsGeneratedBillet(true);
        $billet->setNotBuyable(true);
        $billet->setPosition(9999);
        $em->persist($billet);
        $em->flush();

        $count = $em->getRepository(BilletBuyer::class)->count([]) + 1;

        $order = new BilletBuyer();
        $order->setEvent($event);
        $order->setFirstName($firstName);
        $order->setLastName($lastName);
        $order->setEmail($email);
        $order->setOrderNumber(date('Y-m-d').'-'.$count);
        $order->setTotalHT(0);
        $order->setIsInvitation(true);

        $item = new BilletBuyerItem();
        $item->setBillet($billet);
        $item->setBilletName($billet->getName());
        $item->setQuantity(1);
        $item->setUnitPriceHT(0);
        $order->addItem($item);

        $em->persist($order);
        $em->flush();

        $billetOrderService->generateOrderTickets($order);

        $tickets = $em->getRepository(BilletOrder::class)->findBy(['billetBuyer' => $order]);
        foreach ($tickets as $ticket) {
            $ticket->setIsInvitation(true);
        }
        $em->flush();

        $billetOrderService->generateAndSendTickets($order);

        $this->addFlash('success', 'Accreditation '.$label.' envoyee a '.$order->getEmail().'.');

        return $redirectResponse;
    }

    #[Route('/mon-compte/evenement/{id}/invitation/{orderId}/renvoyer', name: 'app_account_event_resend_invitation', methods: ['POST'])]
    public function resendInvitation(Event $event, int $orderId, EntityManagerInterface $em, BilletOrderService $billetOrderService): Response
    {
        $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
        if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
            return $redirect;
        } // @codeCoverageIgnoreEnd

        $this->requireEventOwnership($event);

        $order = $em->getRepository(BilletBuyer::class)->find($orderId);
        if (!$order || $order->getEvent()->getId() !== $event->getId()) {
            throw $this->createNotFoundException();
        }

        $billetOrderService->generateAndSendTickets($order);

        $this->addFlash('success', 'Invitation renvoyee a '.$order->getEmail().'.');

        return $this->redirectToRoute('app_account_edit_event', ['id' => $event->getId(), 'tab' => 'invitations']);
    }

    #[Route('/mon-compte/evenement/{id}/ticket/{ticketId}/telecharger', name: 'app_account_event_download_ticket', requirements: ['ticketId' => '\d+'], methods: ['GET'])]
    public function downloadTicket(Event $event, int $ticketId, EntityManagerInterface $em, BilletOrderService $billetOrderService): Response
    {
        $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
        $this->requireEventOwnership($event);

        $ticket = $em->getRepository(BilletOrder::class)->find($ticketId);
        if (!$ticket || $ticket->getBilletBuyer()->getEvent()->getId() !== $event->getId()) {
            throw $this->createNotFoundException();
        }

        $pdf = $billetOrderService->generatePdf($ticket);

        return new Response($pdf, 200, [
            'Content-Type' => self::CONTENT_TYPE_PDF,
            'Content-Disposition' => 'inline; filename="'.$ticket->getReference().self::PDF_SUFFIX,
        ]);
    }

    #[Route('/mon-compte/evenement/{id}/ticket/{ticketId}/renvoyer', name: 'app_account_event_resend_ticket', requirements: ['ticketId' => '\d+'], methods: ['POST'])]
    public function resendTicket(Event $event, int $ticketId, EntityManagerInterface $em, BilletOrderService $billetOrderService): Response
    {
        $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
        $this->requireEventOwnership($event);

        $ticket = $em->getRepository(BilletOrder::class)->find($ticketId);
        if (!$ticket || $ticket->getBilletBuyer()->getEvent()->getId() !== $event->getId()) {
            throw $this->createNotFoundException();
        }

        $billetOrderService->generateAndSendTickets($ticket->getBilletBuyer());

        $this->addFlash('success', 'Billet renvoye a '.$ticket->getBilletBuyer()->getEmail().'.');

        return $this->redirectToRoute('app_account_edit_event', ['id' => $event->getId(), 'tab' => 'tickets']);
    }

    #[Route('/mon-compte/evenement/{id}/ticket/{ticketId}/annuler', name: 'app_account_event_cancel_ticket', requirements: ['ticketId' => '\d+'], methods: ['POST'])]
    public function cancelTicket(Event $event, int $ticketId, EntityManagerInterface $em, AuditService $audit): Response
    {
        $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
        $this->requireEventOwnership($event);

        $ticket = $em->getRepository(BilletOrder::class)->find($ticketId);
        if (!$ticket || $ticket->getBilletBuyer()->getEvent()->getId() !== $event->getId()) {
            throw $this->createNotFoundException();
        }

        $ticket->setState(BilletOrder::STATE_INVALID);
        $em->flush();

        $audit->log('ticket_cancelled', 'BilletOrder', $ticket->getId(), [
            'reference' => $ticket->getReference(),
            'event' => $event->getTitle(),
        ]);

        $this->addFlash('success', 'Billet '.$ticket->getReference().' annule.');

        return $this->redirectToRoute('app_account_edit_event', ['id' => $event->getId(), 'tab' => 'tickets']);
    }

    #[Route('/mon-compte/evenement/{id}/attestation', name: 'app_account_event_attestation', methods: ['POST'])]
    public function eventAttestation(Event $event, Request $request, EntityManagerInterface $em): Response
    {
        $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
        $user = $this->requireEventOwnership($event);

        $categoryIds = array_map('intval', $request->request->all('categories'));
        $billetIds = array_map('intval', $request->request->all('billets'));

        $categories = $categoryIds ? $em->getRepository(Category::class)->findBy(['id' => $categoryIds, 'event' => $event]) : [];
        $billets = $billetIds ? array_filter($em->getRepository(Billet::class)->findBy(['id' => $billetIds]), fn (Billet $b) => $b->getCategory()->getEvent()->getId() === $event->getId()) : [];

        if (empty($categories) && empty($billets)) {
            $this->addFlash('error', 'Selectionnez au moins une categorie ou un billet.');

            return $this->redirectToRoute('app_account_edit_event', ['id' => $event->getId(), 'tab' => 'attestation']);
        }

        [$billets, $allBilletIds] = $this->collectAttestationBillets($billets, $categories, $em);
        [$billetLines, $totalSold] = $this->buildAttestationStats($billets, $allBilletIds, $em);
        $ticketDetails = $this->buildAttestationTicketDetails($allBilletIds, $em);

        $isSimple = 'simple' === $request->request->getString('mode', 'detail');
        $generatedAt = new \DateTimeImmutable();
        $selectedCategoryNames = array_map(fn ($c) => $c->getName(), $categories);

        $attestationData = [
            'ref' => 'ATT-'.$event->getId().'-'.$generatedAt->format('YmdHis'),
            'event' => $event->getTitle(),
            'eventDate' => $event->getStartAt()?->format('d/m/Y H:i').' - '.$event->getEndAt()?->format('d/m/Y H:i'),
            'eventLocation' => $event->getAddress().', '.$event->getZipcode().' '.$event->getCity(),
            'organizer' => $user->getCompanyName() ?? $user->getFirstName().' '.$user->getLastName(),
            'siret' => $user->getSiret(),
            'categories' => $selectedCategoryNames,
            'billets' => array_map(fn ($l) => ['cat' => $l['category'], 'name' => $l['name'], 'sold' => $l['sold']], $billetLines),
            'totalSold' => $totalSold,
            'generatedAt' => $generatedAt->format('d/m/Y H:i:s'),
        ];

        $signatureHash = hash_hmac('sha256', json_encode($attestationData, \JSON_UNESCAPED_UNICODE), $this->getParameter('kernel.secret'));

        $attestationEntity = new Attestation(
            $attestationData['ref'],
            $signatureHash,
            $event,
            $user,
            $totalSold,
            $attestationData,
        );
        $em->persist($attestationEntity);
        $em->flush();

        $verifyUrl = $this->generateUrl('app_attestation_ventes_ref', ['reference' => $attestationData['ref']], UrlGeneratorInterface::ABSOLUTE_URL);

        $qrCode = (new \Endroid\QrCode\Builder\Builder(
            writer: new \Endroid\QrCode\Writer\PngWriter(),
            data: $verifyUrl,
            encoding: new \Endroid\QrCode\Encoding\Encoding('UTF-8'),
            size: 300,
            margin: 5,
        ))->build();
        $qrBase64 = 'data:image/png;base64,'.base64_encode($qrCode->getString());

        $html = $this->renderView('pdf/attestation_ventes.html.twig', [
            'event' => $event,
            'organizer' => $user,
            'billetLines' => $billetLines,
            'totalSold' => $totalSold,
            'generatedAt' => $generatedAt,
            'selectedCategories' => $selectedCategoryNames,
            'verifyUrl' => $verifyUrl,
            'qrBase64' => $qrBase64,
            'attestationRef' => $attestationData['ref'],
            'signatureHash' => $signatureHash,
            'isSimple' => $isSimple,
            'ticketDetails' => $ticketDetails,
        ]);

        $dompdf = new \Dompdf\Dompdf();
        $dompdf->loadHtml($html);
        $dompdf->setPaper('A4');
        $dompdf->render();

        return new Response($dompdf->output(), 200, [
            'Content-Type' => self::CONTENT_TYPE_PDF,
            'Content-Disposition' => 'inline; filename="attestation_'.$event->getSlug().'_'.date('Y-m-d').self::PDF_SUFFIX,
        ]);
    }

    #[Route('/mon-compte/evenement/{id}/commande/{orderId}/annuler', name: 'app_account_event_cancel_order', methods: ['POST'])]
    public function cancelOrder(Event $event, int $orderId, EntityManagerInterface $em, AuditService $audit, BilletOrderService $billetOrderService): Response
    {
        $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
        if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
            return $redirect;
        } // @codeCoverageIgnoreEnd

        $this->requireEventOwnership($event);

        $order = $em->getRepository(BilletBuyer::class)->find($orderId);
        if (!$order || $order->getEvent()->getId() !== $event->getId()) {
            throw $this->createNotFoundException();
        }

        $order->setStatus(BilletBuyer::STATUS_CANCELLED);

        $tickets = $em->getRepository(BilletOrder::class)->findBy(['billetBuyer' => $order]);
        foreach ($tickets as $ticket) {
            $ticket->setState(BilletOrder::STATE_INVALID);
        }

        $em->flush();

        $audit->log('order_cancelled', 'BilletBuyer', $order->getId(), [
            'orderNumber' => $order->getOrderNumber(),
            'event' => $event->getTitle(),
        ]);

        $billetOrderService->notifyOrganizerCancelled($order, 'annulee');

        $this->addFlash('success', 'Commande '.$order->getOrderNumber().' annulee.');

        return $this->redirectToRoute('app_account_edit_event', ['id' => $event->getId(), 'tab' => 'stats']);
    }

    /**
     * @codeCoverageIgnore Requires live Stripe API
     */
    #[Route('/mon-compte/evenement/{id}/commande/{orderId}/rembourser', name: 'app_account_event_refund_order', methods: ['POST'])]
    public function refundOrder(Event $event, int $orderId, EntityManagerInterface $em, StripeService $stripeService, AuditService $audit, BilletOrderService $billetOrderService): Response
    {
        $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
        if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
            return $redirect;
        } // @codeCoverageIgnoreEnd

        $user = $this->requireEventOwnership($event);

        $order = $em->getRepository(BilletBuyer::class)->find($orderId);
        if (!$order || $order->getEvent()->getId() !== $event->getId()) {
            throw $this->createNotFoundException();
        }

        if ($order->getStripeSessionId() && $user->getStripeAccountId()) {
            try {
                $stripeService->getClient()->refunds->create([
                    'payment_intent' => $order->getStripeSessionId(),
                ], ['stripe_account' => $user->getStripeAccountId()]);
            } catch (\Exception) {
                // Stripe failure is non-blocking
            }
        }

        $order->setStatus(BilletBuyer::STATUS_REFUNDED);

        $tickets = $em->getRepository(BilletOrder::class)->findBy(['billetBuyer' => $order]);
        foreach ($tickets as $ticket) {
            $ticket->setState(BilletOrder::STATE_INVALID);
        }

        $em->flush();

        $audit->log('order_refunded', 'BilletBuyer', $order->getId(), [
            'orderNumber' => $order->getOrderNumber(),
            'event' => $event->getTitle(),
            'totalHT' => $order->getTotalHTDecimal(),
        ]);

        $billetOrderService->notifyOrganizerCancelled($order, 'remboursee');

        $this->addFlash('success', 'Commande '.$order->getOrderNumber().' remboursee.');

        return $this->redirectToRoute('app_account_edit_event', ['id' => $event->getId(), 'tab' => 'stats']);
    }

    private function buildInvitationOrder(Event $event, Request $request, EntityManagerInterface $em): BilletBuyer|Response
    {
        $firstName = trim($request->request->getString('first_name'));
        $lastName = trim($request->request->getString('last_name'));
        $email = trim($request->request->getString('email'));
        $items = $request->request->all('items');
        $redirect = $this->redirectToRoute('app_account_edit_event', ['id' => $event->getId(), 'tab' => 'invitations']);

        if ('' === $firstName || '' === $lastName || '' === $email || 0 === \count($items)) {
            $this->addFlash('error', 'Tous les champs sont requis.');

            return $redirect;
        }

        $count = $em->getRepository(BilletBuyer::class)->count([]) + 1;

        $order = new BilletBuyer();
        $order->setEvent($event);
        $order->setFirstName($firstName);
        $order->setLastName($lastName);
        $order->setEmail($email);
        $order->setOrderNumber(date('Y-m-d').'-'.$count);
        $order->setTotalHT(0);
        $order->setIsInvitation(true);

        foreach ($items as $itemData) {
            $billetId = (int) ($itemData['billet_id'] ?? 0);
            $qty = max(1, (int) ($itemData['quantity'] ?? 1));

            $billet = $em->getRepository(Billet::class)->find($billetId);
            if (!$billet || $billet->getCategory()->getEvent()->getId() !== $event->getId()) {
                continue;
            }

            $item = new BilletBuyerItem();
            $item->setBillet($billet);
            $item->setBilletName($billet->getName());
            $item->setQuantity($qty);
            $item->setUnitPriceHT(0);
            $order->addItem($item);
        }

        if ($order->getItems()->isEmpty()) {
            $this->addFlash('error', 'Aucun billet valide selectionne.');

            return $redirect;
        }

        return $order;
    }

    /**
     * @param list<Billet>   $billets
     * @param list<Category> $categories
     *
     * @return array{list<Billet>, list<int>}
     */
    private function collectAttestationBillets(array $billets, array $categories, EntityManagerInterface $em): array
    {
        $allBilletIds = array_map(fn (Billet $b) => $b->getId(), $billets);

        foreach ($categories as $cat) {
            foreach ($em->getRepository(Billet::class)->findBy(['category' => $cat]) as $b) {
                if (!\in_array($b->getId(), $allBilletIds, true)) {
                    $allBilletIds[] = $b->getId();
                    $billets[] = $b;
                }
            }
        }

        return [$billets, $allBilletIds];
    }

    /**
     * @param list<Billet> $billets
     * @param list<int>    $allBilletIds
     *
     * @return array{list<array<string, mixed>>, int}
     */
    private function buildAttestationStats(array $billets, array $allBilletIds, EntityManagerInterface $em): array
    {
        $soldCounts = [];
        if ($allBilletIds) {
            $rows = $em->createQueryBuilder()
                ->select('IDENTITY(bo.billet) AS billetId, COUNT(bo.id) AS cnt')
                ->from(BilletOrder::class, 'bo')
                ->join('bo.billetBuyer', 'bb')
                ->where('bo.billet IN (:ids)')
                ->andWhere(self::DQL_BB_EXCLUDE_INVITATIONS)
                ->setParameter('ids', $allBilletIds)
                ->groupBy('bo.billet')
                ->getQuery()
                ->getArrayResult();
            foreach ($rows as $row) {
                $soldCounts[(int) $row['billetId']] = (int) $row['cnt'];
            }
        }

        $billetLines = [];
        $totalSold = 0;
        foreach ($billets as $b) {
            $sold = $soldCounts[$b->getId()] ?? 0;
            $billetLines[] = [
                'category' => $b->getCategory()->getName(),
                'name' => $b->getName(),
                'sold' => $sold,
            ];
            $totalSold += $sold;
        }

        return [$billetLines, $totalSold];
    }

    /**
     * @param list<int> $allBilletIds
     *
     * @return list<array<string, mixed>>
     */
    private function buildAttestationTicketDetails(array $allBilletIds, EntityManagerInterface $em): array
    {
        if (!$allBilletIds) {
            return [];
        }

        $tickets = $em->createQueryBuilder()
            ->select('t', 'bb')
            ->from(BilletOrder::class, 't')
            ->join('t.billetBuyer', 'bb')
            ->where('t.billet IN (:ids)')
            ->andWhere(self::DQL_BB_EXCLUDE_INVITATIONS)
            ->setParameter('ids', $allBilletIds)
            ->orderBy('t.createdAt', 'ASC')
            ->getQuery()
            ->getResult();

        $details = [];
        foreach ($tickets as $t) {
            $details[] = [
                'reference' => $t->getReference(),
                'billetName' => $t->getBilletName(),
                'orderNumber' => $t->getBilletBuyer()->getOrderNumber(),
                'buyerName' => $t->getBilletBuyer()->getFirstName().' '.$t->getBilletBuyer()->getLastName(),
            ];
        }

        return $details;
    }

    /** @codeCoverageIgnore Generates PDF with dompdf */
    #[Route('/mon-compte/payout/{id}/attestation', name: 'app_account_payout_pdf')]
    public function payoutPdf(Payout $payout, PayoutPdfService $pdfService): Response
    {
        /** @var User $user */
        $user = $this->getUser();

        if ($payout->getOrganizer()->getId() !== $user->getId()) {
            throw $this->createAccessDeniedException();
        }

        return new Response($pdfService->generate($payout), 200, [
            'Content-Type' => self::CONTENT_TYPE_PDF,
            'Content-Disposition' => 'inline; filename="attestation_'.$payout->getStripePayoutId().self::PDF_SUFFIX,
        ]);
    }

    #[Route('/mon-compte/export/{year}/{month}', name: 'app_account_export', requirements: ['year' => '\d{4}', 'month' => '\d{1,2}'], methods: ['GET'])]
    public function export(int $year, int $month, ExportService $exportService): Response
    {
        $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
        if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
            return $redirect;
        } // @codeCoverageIgnoreEnd

        /** @var User $user */
        $user = $this->getUser();
        $stats = $exportService->getMonthlyStats($year, $month, $user);
        $csv = $exportService->generateCsv($stats['orders']);

        $filename = sprintf('export_%04d_%02d.csv', $year, $month);

        return new Response($csv, 200, [
            'Content-Type' => 'text/csv; charset=utf-8',
            'Content-Disposition' => 'attachment; filename="'.$filename.'"',
        ]);
    }

    #[Route('/mon-compte/export/{year}/{month}/pdf', name: 'app_account_export_pdf', requirements: ['year' => '\d{4}', 'month' => '\d{1,2}'], methods: ['GET'])]
    public function exportPdf(int $year, int $month, ExportService $exportService): Response
    {
        $this->denyAccessUnlessGranted('ROLE_ORGANIZER');
        if ($redirect = $this->requireStripeReady()) { // @codeCoverageIgnoreStart
            return $redirect;
        } // @codeCoverageIgnoreEnd

        /** @var User $user */
        $user = $this->getUser();
        $stats = $exportService->getMonthlyStats($year, $month, $user);
        $pdf = $exportService->generatePdf($stats, $year, $month, $user);

        $filename = sprintf('recap_%04d_%02d.pdf', $year, $month);

        return new Response($pdf, 200, [
            'Content-Type' => self::CONTENT_TYPE_PDF,
            'Content-Disposition' => 'inline; filename="'.$filename.'"',
        ]);
    }
}
