<?php

class FileUpload {

    protected static $base_path = __DIR__ . '/../../../public/';
    protected static $base_url = '/public/';

    // === Маппинг сущностей (все параметры обязательны) ===
    protected static $entities = [
        'task' => [
            'table' => 'cards_task',
            'folder' => 'task',
            'field' => 'file_img',
            'allowed_ext' => ['png', 'jpg', 'jpeg', 'zip', 'rar'],
            'archive_ext' => ['zip', 'rar'],
            'max_size' => 10 * 1024 * 1024  // 10 MB
        ],
        'comment' => [
            'table' => 'comments',
            'folder' => 'comment',
            'field' => 'file_img',
            'allowed_ext' => ['png', 'jpg', 'jpeg', 'zip', 'rar'],
            'archive_ext' => ['zip', 'rar'],
            'max_size' => 10 * 1024 * 1024  // 10 MB
        ]
    ];

    // Получение конфигурации сущности
    protected static function getConfig($entity_type) {
        if (!isset(self::$entities[$entity_type])) {
            return null;
        }
        return self::$entities[$entity_type];
    }

    // Получение данных сущности из БД
    protected static function getEntityData($config, $entity_id) {
        return Database::get($config['table'], '*', ['id' => $entity_id]);
    }

    // Обновление файлов сущности в БД
    protected static function updateEntityFiles($config, $entity_id, $files) {
        Database::update($config['table'], [
            $config['field'] => json_encode($files, JSON_UNESCAPED_UNICODE)
        ], [
            'id' => $entity_id
        ]);
    }

    // Генерация уникального имени файла
    protected static function getUniqueName($upload_dir, $file_name) {
        $ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
        $base_name = pathinfo($file_name, PATHINFO_FILENAME);
        $final_name = $file_name;
        $counter = 1;

        while (file_exists($upload_dir . '/' . $final_name)) {
            $final_name = $base_name . '_' . $counter . '.' . $ext;
            $counter++;
        }

        return $final_name;
    }

    // Форматирование размера файла для ошибки
    protected static function formatSize($bytes) {
        if ($bytes >= 1048576) {
            return round($bytes / 1048576, 1) . ' МБ';
        }
        return round($bytes / 1024, 1) . ' КБ';
    }

    // === ЗАГРУЗКА ФАЙЛА ===
    public static function upload($entity_type, $entity_id, $file_base64, $file_name) {
        // Получаем конфигурацию
        $config = self::getConfig($entity_type);
        if (!$config) {
            return ['success' => false, 'errors' => ['entity' => 'Неизвестный тип сущности']];
        }

        // Проверяем что сущность существует
        $entity = self::getEntityData($config, $entity_id);
        if (!$entity) {
            return ['success' => false, 'errors' => ['entity' => 'Сущность не найдена']];
        }

        // Декодируем base64
        $file_data = base64_decode(preg_replace('/^data:[^;]+;base64,/', '', $file_base64));
        if (!$file_data) {
            return ['success' => false, 'errors' => ['file' => 'Ошибка декодирования файла']];
        }

        // Проверка расширения
        $ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
        if (!in_array($ext, $config['allowed_ext'])) {
            $allowed = strtoupper(implode(', ', $config['allowed_ext']));
            return ['success' => false, 'errors' => ['file' => "Разрешены только: $allowed"]];
        }

        // Проверка размера
        $file_size = strlen($file_data);
        if ($file_size > $config['max_size']) {
            $max_formatted = self::formatSize($config['max_size']);
            return ['success' => false, 'errors' => ['file' => "Файл слишком большой. Максимум $max_formatted"]];
        }

        // Путь к папке
        $upload_dir = self::$base_path . $config['folder'] . '/' . $entity_id;
        if (!is_dir($upload_dir)) {
            mkdir($upload_dir, 0755, true);
        }

        // Уникальное имя
        $final_name = self::getUniqueName($upload_dir, $file_name);

        // Сохранение файла
        $file_path = $upload_dir . '/' . $final_name;
        if (!file_put_contents($file_path, $file_data)) {
            return ['success' => false, 'errors' => ['file' => 'Ошибка сохранения файла']];
        }

        // Формируем URL
        $file_url = self::$base_url . $config['folder'] . '/' . $entity_id . '/' . $final_name;

        // Обновляем file_img в базе
        $current_files = $entity[$config['field']] ? json_decode($entity[$config['field']], true) : [];
        $current_files[] = [
            'url' => $file_url,
            'name' => $final_name,
            'size' => $file_size
        ];

        self::updateEntityFiles($config, $entity_id, $current_files);

        return [
            'success' => true,
            'file' => [
                'url' => $file_url,
                'name' => $final_name,
                'size' => $file_size
            ]
        ];
    }

    // === УДАЛЕНИЕ ФАЙЛОВ ===
    public static function delete($entity_type, $entity_id, $file_names) {
        // Получаем конфигурацию
        $config = self::getConfig($entity_type);
        if (!$config) {
            return ['success' => false, 'errors' => ['entity' => 'Неизвестный тип сущности']];
        }

        // Проверяем что сущность существует
        $entity = self::getEntityData($config, $entity_id);
        if (!$entity) {
            return ['success' => false, 'errors' => ['entity' => 'Сущность не найдена']];
        }

        // Приводим к массиву если передана строка
        if (!is_array($file_names)) {
            $file_names = [$file_names];
        }

        // Получаем текущие файлы
        $current_files = $entity[$config['field']] ? json_decode($entity[$config['field']], true) : [];
        $upload_dir = self::$base_path . $config['folder'] . '/' . $entity_id;
        $deleted = [];

        // Удаляем каждый файл
        foreach ($file_names as $file_name) {
            foreach ($current_files as $index => $file) {
                if ($file['name'] === $file_name) {
                    // Удаляем файл с диска
                    $file_path = $upload_dir . '/' . $file_name;
                    if (file_exists($file_path)) {
                        unlink($file_path);
                    }
                    // Удаляем из массива
                    array_splice($current_files, $index, 1);
                    $deleted[] = $file_name;
                    break;
                }
            }
        }

        // Обновляем в базе
        self::updateEntityFiles($config, $entity_id, $current_files);

        // Удаляем папку если она пустая
        if (is_dir($upload_dir) && count(scandir($upload_dir)) === 2) {
            rmdir($upload_dir);
        }

        return ['success' => true, 'deleted' => $deleted];
    }

    // === УДАЛЕНИЕ ПАПКИ СУЩНОСТИ (при удалении самой сущности) ===
    public static function deleteFolder($entity_type, $entity_id) {
        // Получаем конфигурацию
        $config = self::getConfig($entity_type);
        if (!$config) {
            return false;
        }

        $upload_dir = self::$base_path . $config['folder'] . '/' . $entity_id;
        
        if (is_dir($upload_dir)) {
            // Удаляем все файлы в папке
            $files = glob($upload_dir . '/*');
            foreach ($files as $file) {
                if (is_file($file)) {
                    unlink($file);
                }
            }
            // Удаляем папку
            rmdir($upload_dir);
        }

        return true;
    }
}

?>
