<?php
declare(strict_types=1);

namespace Leadlion\SmartBill\Controller\Adminhtml\Invoice;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\Response\Http\FileFactory;
use Magento\Framework\Controller\Result\RawFactory;
use Magento\Framework\Filesystem;

class Download extends Action
{
    const ADMIN_RESOURCE = 'Magento_Sales::sales_order';

    private Filesystem $filesystem;
    private RawFactory $resultRawFactory;

    public function __construct(
        Context $context,
        Filesystem $filesystem,
        RawFactory $resultRawFactory
    ) {
        parent::__construct($context);
        $this->filesystem = $filesystem;
        $this->resultRawFactory = $resultRawFactory;
    }

    public function execute()
    {
        $fileEncoded = $this->getRequest()->getParam('file');

        if (empty($fileEncoded)) {
            $this->messageManager->addErrorMessage(__('File not specified.'));
            return $this->_redirect('sales/order/index');
        }

        $file = base64_decode($fileEncoded, true);
        if ($file === false) {
            $this->messageManager->addErrorMessage(__('Invalid file parameter.'));
            return $this->_redirect('sales/order/index');
        }

        // Sanitize: no traversal
        $file = ltrim($file, '/');
        if (strpos($file, '..') !== false || strpos($file, "\0") !== false) {
            $this->messageManager->addErrorMessage(__('Invalid file path.'));
            return $this->_redirect('sales/order/index');
        }

        $varDir = $this->filesystem->getDirectoryRead(DirectoryList::VAR_DIR)->getAbsolutePath();
        $absPath = $varDir . 'smartbill/inv/' . $file;

        if (!is_file($absPath) || !file_exists($absPath)) {
            $this->messageManager->addErrorMessage(__('File not found.'));
            return $this->_redirect('sales/order/index');
        }

        $result = $this->resultRawFactory->create();
        $result->setHttpResponseCode(200);
        $result->setHeader('Content-Type', 'application/pdf', true);
        $result->setHeader('Content-Disposition', 'inline; filename="' . basename($absPath) . '"', true);
        $result->setHeader('Content-Length', (string)filesize($absPath), true);
        $result->setContents(file_get_contents($absPath));

        return $result;
    }
}
