<?php

namespace Bastion\Tasks;

use DateInterval;
use Exception;
use JsonException;
use Openguru\OpenCartFramework\MaintenanceTasks\BaseMaintenanceTask;
use RuntimeException;

class CleanUpOldAssetsTask extends BaseMaintenanceTask
{
    public function handle(): void
    {
        $spaPath = rtrim(DIR_IMAGE, '/') . '/catalog/tgshopspa';
        $assetsPath = $spaPath . '/assets';
        $manifestPath = $spaPath . '/manifest.json';
        if (! file_exists($manifestPath)) {
            return;
        }

        try {
            $contents = json_decode(file_get_contents($manifestPath), true, 512, JSON_THROW_ON_ERROR);

            $entry = $contents['index.html'] ?? null;
            if (! $entry) {
                throw new RuntimeException('Некорректный manifest.json — отсутствует ключ index.html.');
            }

            $keep = [$entry['file']];
            if (! empty($entry['css'])) {
                foreach ($entry['css'] as $css) {
                    $keep[] = $css;
                }
            }

            $deletedFiles = 0;
            $keptFiles = 0;

            foreach (glob($assetsPath . '/*') as $file) {
                $ext = pathinfo($file, PATHINFO_EXTENSION);
                if (! in_array($ext, ['js', 'css', 'map'])) {
                    continue;
                }
                $relative = 'assets/' . basename($file);
                if (in_array($relative, $keep, true)) {
                    $keptFiles++;
                    continue;
                }

                if (is_file($file)) {
                    unlink($file);
                    $deletedFiles++;
                }
            }

            if ($deletedFiles > 0) {
                $this->logger->info(
                    sprintf('Очистка assets завершена. Удалено: %d, оставлено: %d', $deletedFiles, $keptFiles)
                );
            }
        } catch (JsonException $e) {
            $this->logger->error('Ошибка декодирования файла manifest.json: ' . $e->getMessage());
        } catch (Exception $e) {
            $this->logger->error('Ошибка удаления старых assets: ' . $e->getMessage(), ['exception' => $e]);
        }
    }

    public function interval(): ?DateInterval
    {
        return new DateInterval('PT1H');
    }
}
