<?php

declare(strict_types=1);

namespace Gls\GlsPoland\Download;

use Gls\GlsPoland\AdePlus\Printout\NamedPrintoutInterface;
use Gls\GlsPoland\AdePlus\Printout\PrintModeInterface;
use Gls\GlsPoland\AdePlus\Printout\PrintoutInterface;
use ZipStream\Option\Archive;
use ZipStream\ZipStream;

final class Base64EncodedFilesArchive implements StreamableFileInterface
{
    private $printouts;
    private $printMode;

    /**
     * @param iterable<PrintoutInterface> $printouts
     */
    public function __construct(iterable $printouts, PrintModeInterface $printMode)
    {
        $this->printouts = $printouts;
        $this->printMode = $printMode;
    }

    public function stream(): void
    {
        $options = new Archive();
        $options->setFlushOutput(true);

        $zip = new ZipStream(null, $options);

        foreach ($this->printouts as $index => $printout) {
            $stream = fopen('php://temporary', 'rb+');

            try {
                stream_filter_append($stream, 'convert.base64-decode', STREAM_FILTER_WRITE);
                fwrite($stream, $printout->getContents());
                fseek($stream, 0);

                $fileName = $printout instanceof NamedPrintoutInterface
                    ? $printout->getFileName()
                    : $index;

                $zip->addFileFromStream(sprintf('%s.%s', $fileName, $this->printMode->getFileExtension()), $stream);
            } finally {
                fclose($stream);
            }
        }

        $zip->finish();
    }

    public function getContentType(): string
    {
        return 'application/x-zip';
    }

    public function getFileExtension(): string
    {
        return 'zip';
    }
}
