<?php

declare(strict_types=1);

namespace Flowaxy\Support\Helpers;

use Flowaxy\Support\Facades\Log;
use Exception;

use function array_diff;
use function file_exists;
use function filemtime;
use function glob;
use function is_array;
use function is_dir;
use function is_file;
use function method_exists;
use function rmdir;
use function scandir;
use function time;
use function unlink;
use const DS;

// Хелпер для централизованной очистки ресурсов
final class ResourceCleanupHelper
{
    // Очистка ZIP архива
    public static function cleanupZip(?object $zip = null): bool
    {
        if (!$zip) {
            return true;
        }

        try {
            if (method_exists($zip, 'close')) {
                $zip->close();
                return true;
            }
        } catch (Exception $e) {
            Log::Warning('ResourceCleanupHelper: Error closing ZIP archive', [
                'error' => $e->getMessage(),
            ]);
        }

        return false;
    }

    // Очистка временных файлов
    public static function cleanupTempFiles(string|array $files): int
    {
        $files = is_array($files) ? $files : [$files];
        $deleted = 0;

        foreach ($files as $file) {
            if ($file && file_exists($file)) {
                try {
                    if (@unlink($file)) {
                        $deleted++;
                    } else {
                        Log::Warning('ResourceCleanupHelper: Failed to delete temp file', [
                            'file' => $file,
                        ]);
                    }
                } catch (Exception $e) {
                    Log::Warning('ResourceCleanupHelper: Error deleting temp file', [
                        'file' => $file,
                        'error' => $e->getMessage(),
                    ]);
                }
            }
        }

        return $deleted;
    }

    // Очистка ресурсов при ошибке
    public static function cleanupOnError(?object $zip = null, string|array|null $files = null, ?string $directory = null): void
    {
        // Закрываем ZIP архив
        self::cleanupZip($zip);

        // Удаляем временные файлы
        if ($files !== null) {
            self::cleanupTempFiles($files);
        }

        // Удаляем директорию, если указана
        if ($directory !== null && is_dir($directory)) {
            self::deleteDirectory($directory);
        }
    }

    // Рекурсивное удаление директории
    public static function deleteDirectory(string $dir): bool
    {
        if (!is_dir($dir)) {
            return false;
        }

        try {
            $files = array_diff(scandir($dir), ['.', '..']);

            foreach ($files as $file) {
                $path = $dir . DS . $file;
                if (is_dir($path)) {
                    self::deleteDirectory($path);
                } else {
                    @unlink($path);
                }
            }

            return @rmdir($dir);
        } catch (Exception $e) {
            Log::Warning('ResourceCleanupHelper: Error deleting directory', [
                'directory' => $dir,
                'error' => $e->getMessage(),
            ]);
            return false;
        }
    }

    // Очистка старых временных файлов
    public static function cleanupOldTempFiles(string $directory, int $maxAge = 86400): int
    {
        if (!is_dir($directory)) {
            return 0;
        }

        $deleted = 0;
        $now = time();

        try {
            $files = glob($directory . '*');
            if ($files === false) {
                return 0;
            }

            foreach ($files as $file) {
                if (is_file($file)) {
                    $fileAge = $now - filemtime($file);
                    if ($fileAge > $maxAge) {
                        if (@unlink($file)) {
                            $deleted++;
                        }
                    }
                }
            }
        } catch (Exception $e) {
            Log::Warning('ResourceCleanupHelper: Error cleaning old temp files', [
                'directory' => $directory,
                'error' => $e->getMessage(),
            ]);
        }

        return $deleted;
    }
}
