<?php

namespace App\Manager;

use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\String\Slugger\SluggerInterface;

class FileSystemManager
{
    private const string CBZ_DIRECTORY = 'public/cbz';
    private const string UPLOADS_DIRECTORY = 'public/tmp';
    private const string IMAGES_DIRECTORY = 'public/images';

    private string $mangaDirectory;
    private string $imageDirectory;

    public function __construct(
        private readonly string $projectDir,
        private readonly Filesystem $filesystem,
        private readonly SluggerInterface $slugger,
        private readonly AppSettingsManager $appSettingsManager
    ) {
        $this->loadSettings();
    }

    private function loadSettings(): void
    {
        $settings = $this->appSettingsManager->getSettings();
        $this->mangaDirectory = $settings->getMangaDirectory();
        $this->imageDirectory = $settings->getImageDirectory();
    }

    public function getMangaDirectory(): string
    {
        return $this->mangaDirectory;
    }

    public function getImageDirectory(): string
    {
        return $this->imageDirectory;
    }

    public function getImagePath(string $subDir = ''): string
    {
        if (!$this->filesystem->exists($this->projectDir.'/'.self::IMAGES_DIRECTORY.($subDir ? "/$subDir" : ''))) {
            $this->filesystem->mkdir($this->projectDir.'/'.self::IMAGES_DIRECTORY.($subDir ? "/$subDir" : ''), 0755);
        }

        return $this->projectDir.'/'.self::IMAGES_DIRECTORY.($subDir ? "/$subDir" : '');
    }

    public function createMangaDirectory(string $mangaSlug, ?int $year): string
    {
        $year = $year ?? 'unknown';
        $directoryPath = $this->projectDir.'/'.self::CBZ_DIRECTORY.'/'.ucfirst($mangaSlug)." ($year)";
        $this->filesystem->mkdir($directoryPath, 0755);

        return $directoryPath;
    }

    public function createVolumeDirectory(string $mangaDir, int $volume): string
    {
        $volumeDir = sprintf('%s/volume_%02d', $mangaDir, $volume);
        $this->filesystem->mkdir($volumeDir, 0755);

        return $volumeDir;
    }

    public function moveUploadedFile(string $sourcePath, string $destinationDir, string $originalFilename): string
    {
        $newFilename = $this->generateUniqueFilename($originalFilename);
        $destinationPath = $destinationDir.'/'.$newFilename;
        $this->filesystem->rename($sourcePath, $destinationPath, true);

        return $destinationPath;
    }

    public function deleteFile(string $filePath): void
    {
        if ($this->filesystem->exists($filePath)) {
            $this->filesystem->remove($filePath);
        }
    }

    public function deleteDirectory(string $directoryPath): void
    {
        if ($this->filesystem->exists($directoryPath)) {
            $this->filesystem->remove($directoryPath);
        }
    }

    public function fileExists(string $filePath): bool
    {
        return $this->filesystem->exists($filePath);
    }

    public function moveFile(string $sourcePath, string $destinationPath): void
    {
        $this->filesystem->rename($sourcePath, $destinationPath, true);
    }

    public function getUploadsDirectory(): string
    {
        return $this->projectDir.'/'.self::UPLOADS_DIRECTORY;
    }

    private function generateUniqueFilename(string $originalFilename): string
    {
        $safeFilename = $this->slugger->slug(pathinfo($originalFilename, PATHINFO_FILENAME));

        return $safeFilename.'-'.uniqid().'.'.pathinfo($originalFilename, PATHINFO_EXTENSION);
    }

    public function generateUniqueImageFilename(string $originalFilename): string
    {
        $safeFilename = $this->slugger->slug(pathinfo($originalFilename, PATHINFO_FILENAME));

        return $safeFilename.'-'.uniqid().'.jpg';
    }
}
