<?php
declare(strict_types=1);

namespace Autogedal\EanTools\Controller\Adminhtml\Download;

use Autogedal\EanTools\Controller\Adminhtml\AbstractTool;
use Autogedal\EanTools\Model\ResultStorage;
use Autogedal\EanTools\Model\Spreadsheet\Format;
use Magento\Backend\App\Action\Context;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\Response\Http\FileFactory;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\View\Result\PageFactory;
use Psr\Log\LoggerInterface;

class Index extends AbstractTool implements HttpGetActionInterface
{
    public function __construct(
        Context $context,
        PageFactory $resultPageFactory,
        private readonly ResultStorage $storage,
        private readonly FileFactory $fileFactory,
        private readonly Format $format,
        private readonly LoggerInterface $logger
    ) {
        parent::__construct($context, $resultPageFactory);
    }

    public function execute(): ResultInterface|ResponseInterface
    {
        $runId = (string)$this->getRequest()->getParam('run', '');
        $file = (string)$this->getRequest()->getParam('file', '');

        try {
            $relativePath = $this->storage->getRelativeFilePath($runId, $file);

            return $this->fileFactory->create(
                $file,
                ['type' => 'filename', 'value' => $relativePath, 'rm' => false],
                DirectoryList::VAR_DIR,
                $this->getContentType($file)
            );
        } catch (LocalizedException $e) {
            $this->messageManager->addErrorMessage($e->getMessage());
        } catch (\Throwable $e) {
            $this->logger->error('Autogedal_EanTools download: ' . $e->getMessage(), ['exception' => $e]);
            $this->messageManager->addErrorMessage((string)__('The file could not be downloaded.'));
        }

        return $this->redirectTo('*/index/index');
    }

    private function getContentType(string $fileName): string
    {
        if (str_ends_with($fileName, '.json')) {
            return 'application/json';
        }

        try {
            return $this->format->getMimeType($this->format->fromFileName($fileName));
        } catch (LocalizedException) {
            return 'application/octet-stream';
        }
    }
}
