<?php

declare(strict_types=1);

namespace External\PompoBundle\Util;

use External\PompoBundle\Exception\PompoException;
use KupShop\KupShopBundle\Util\FileUtil;
use KupShop\KupShopBundle\Util\System\PathFinder;

class PompoContentUtil
{
    public const CONTENT_TYPE_SECTION = 'section';
    public const CONTENT_TYPE_PRODUCER = 'producer';

    private PathFinder $pathFinder;

    public function __construct(PathFinder $pathFinder)
    {
        $this->pathFinder = $pathFinder;
    }

    public function uploadContent(array $file, string $subfolder, string $type): bool
    {
        // zkontroluju, ze nahravaji ZIP soubor
        if (!in_array($file['type'], $this->getZipMimeTypes())) {
            throw new PompoException('Nahrávaný soubor musí být ZIP soubor');
        }

        $tmpPath = $this->pathFinder->dataPath($type.'/pompo_content/_tmp_'.$subfolder);
        $savePath = $this->getContentPath($subfolder, $type);

        // smazu aktualni content
        if (file_exists($savePath)) {
            FileUtil::deleteDir($savePath);
        }

        // vytvorim slozku
        if (!file_exists($tmpPath)) {
            mkdir($tmpPath, 0777, true);
        }

        $originalTmpPath = $tmpPath;

        $zip = new \ZipArchive();
        // rozbalim zip
        if ($zip->open($file['tmp_name'])) {
            // Rozbalim si ZIP do tmp slozky
            $zip->extractTo($tmpPath);
            $zip->close();

            $files = array_filter(scandir($tmpPath), function ($x) { return !empty(trim($x, '.')); });
            // Pokud je v ZIPu jeste slozka, ve ktere ten obsah je, tak to z ni vytahnu
            if (count($files) === 1) {
                if ($dir = reset($files)) {
                    $tmpPath .= '/'.$dir;
                }
            }
            // Presunu soubory do slozky, kde je ocekavam
            rename($tmpPath, $savePath);
        }

        // Smazu tmp slozku
        FileUtil::deleteDir($originalTmpPath);

        return true;
    }

    public function deleteCustomContent(string $subfolder, string $type): bool
    {
        $path = $this->getContentPath($subfolder, $type);
        if (file_exists($path)) {
            FileUtil::deleteDir($path);
        }

        return true;
    }

    public function downloadCustomContent(string $subfolder, string $type): void
    {
        $path = $this->getContentPath($subfolder, $type);

        if (file_exists($path)) {
            $zip = new \ZipArchive();
            $tmpFile = tempnam($this->pathFinder->getTmpDir(), 'pompo_content_');
            $zip->open($tmpFile, \ZipArchive::CREATE);

            $dir = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS);
            $files = new \RecursiveIteratorIterator($dir, \RecursiveIteratorIterator::CHILD_FIRST);
            // nahazet soubory do zipu
            foreach ($files as $file) {
                if ($file->isDir()) {
                    continue;
                }

                $zipName = ltrim($file->getPathname(), $path);
                $zip->addFile($file->getPathname(), $zipName);
            }

            if ($result = $zip->close()) {
                header('Content-disposition: attachment; filename='.$type.'_content_'.$subfolder.'.zip');
                header('Content-type: application/zip');
                readfile($tmpFile);

                unlink($tmpFile);

                return;
            }

            unlink($tmpFile);

            throw new PompoException('Vlastní obsah se nepodařilo stáhnout.', '', [
                'result' => $result,
                'zipStatusString' => $zip->getStatusString(),
                'type' => $type,
                'folder' => $subfolder,
            ]);
        }

        throw new PompoException('Nebyl nalezen žádný vlastní obsah.');
    }

    private function getContentPath(string $subfolder, string $type): string
    {
        return $this->pathFinder->dataPath($type.'/pompo_content/'.$subfolder);
    }

    private function getZipMimeTypes(): array
    {
        return ['application/zip', 'application/octet-stream', 'application/x-zip-compressed', 'multipart/x-zip'];
    }
}
