<?php

namespace Console\Commands;

use Openguru\OpenCartFramework\Container\Container;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

class ImagesCacheClearCommand extends TeleCartCommand
{
    protected static $defaultName = 'images:cache-clear';
    protected static $defaultDescription = 'Очистка кеша изображений товаров';

    private Container $container;

    public function __construct(Container $container)
    {
        parent::__construct();
        $this->container = $container;
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);

        $io->title('Очистка кеша изображений товаров');

        // Получаем пути из конфига
        $imagesDir = $this->container->getConfigValue('paths.images');
        $cachePath = $this->container->getConfigValue('paths.images_cache', 'cache/telecart');
        $cachePath = ltrim($cachePath, '/');
        $fullCachePath = rtrim($imagesDir, '/') . '/' . $cachePath;

        if (!is_dir($fullCachePath)) {
            $io->warning("Директория кеша не существует: {$fullCachePath}");
            return Command::SUCCESS;
        }

        $io->section('Информация');
        $io->listing([
            "Директория изображений: {$imagesDir}",
            "Путь кеша: {$cachePath}",
            "Полный путь кеша: {$fullCachePath}",
        ]);

        // Подсчитываем файлы перед удалением
        $fileCount = 0;
        $totalSize = 0;
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($fullCachePath, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::CHILD_FIRST
        );

        foreach ($iterator as $file) {
            if ($file->isFile()) {
                $fileCount++;
                $totalSize += $file->getSize();
            }
        }

        if ($fileCount === 0) {
            $io->info('Кеш пуст, нечего очищать.');
            return Command::SUCCESS;
        }

        $io->section('Статистика перед очисткой');
        $io->listing([
            "Файлов: {$fileCount}",
            "Размер: " . $this->formatBytes($totalSize),
        ]);

        // Запрашиваем подтверждение
        if (!$io->confirm('Вы уверены, что хотите удалить все файлы из кеша?', false)) {
            $io->info('Очистка кеша отменена.');
            return Command::SUCCESS;
        }

        // Удаляем файлы и директории
        $deletedFiles = 0;
        $deletedDirs = 0;
        $errors = 0;

        $progressBar = $io->createProgressBar($fileCount);
        $progressBar->setFormat(' %current%/%max% [%bar%] %percent:3s%% %message%');
        $progressBar->setMessage('Удаление файлов...');
        $progressBar->start();

        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($fullCachePath, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::CHILD_FIRST
        );

        foreach ($iterator as $file) {
            try {
                if ($file->isFile()) {
                    if (@unlink($file->getPathname())) {
                        $deletedFiles++;
                    } else {
                        $errors++;
                    }
                    $progressBar->advance();
                } elseif ($file->isDir()) {
                    if (@rmdir($file->getPathname())) {
                        $deletedDirs++;
                    }
                }
            } catch (\Exception $e) {
                $errors++;
            }
        }

        // Удаляем саму директорию кеша, если она пуста
        if (is_dir($fullCachePath)) {
            @rmdir($fullCachePath);
        }

        $progressBar->setMessage('Завершено');
        $progressBar->finish();
        $io->newLine(2);

        // Выводим статистику
        $io->section('Результаты');
        $io->table(
            ['Метрика', 'Значение'],
            [
                ['Удалено файлов', $deletedFiles],
                ['Удалено директорий', $deletedDirs],
                ['Ошибок', $errors],
            ]
        );

        if ($errors > 0) {
            $io->warning("Обнаружено {$errors} ошибок при удалении файлов.");
        } else {
            $io->success('Кеш изображений успешно очищен!');
        }

        return Command::SUCCESS;
    }

    private function formatBytes(int $bytes, int $precision = 2): string
    {
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];

        for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
            $bytes /= 1024;
        }

        return round($bytes, $precision) . ' ' . $units[$i];
    }
}

