<?php
    /*
        *****************************************************************************
        * MEGA Digital Space - by MEGA Digital Studio                               *
        * ------------------------------------------------------------------------- *
        * CMS Website:  https://megadigital.space                                   *
        * License:  https://megadigital.space/license                               *
        * Owner:  Giorgi Basharuli                                                  *
        * Contact:  online@megadigital.studio                                       *
        * MEGA Digital Studio – Official Development Studio for MEGA Digital Space  *
        * Website:  https://megadigital.studio                                      *
        * ------------------------------------------------------------------------- *
        * Description: This file is a part of the MEGA Digital Space CMS system.    *
        * Unauthorized distribution, modification, or commercial use is strictly -  *
        * prohibited without prior written permission.                              *
        * ------------------------------------------------------------------------- *
        * Copyright (c) 2023-2025 MEGA Digital Studio.                              *
        * All rights reserved.                                                      *
        *****************************************************************************
    */

    require_once(ENGINE_DIR . '/data/config.php');
    require_once(SYSTEM_DIR. '/plugins/reserved_fm_names.php');

    class FileManager {
        public $rootDir = './';
        private $currentPath;
        private $db;

        public function __construct($db) {
            $this->db = $db;
            $requestedPath = isset($_GET['path']) ? trim($_GET['path'], '/') : '';
            $this->currentPath = $this->rootDir . ($requestedPath ? '/' . $requestedPath : '');
        }

        public function getCurrentPath($relative = false) {
            // Возвращает относительный или полный путь
            return $relative
                ? (isset($_GET['path']) ? trim($_GET['path'], '/') : '')
                : $this->currentPath;
        }

        public function getParentPath() {
            $parentPath = dirname($this->currentPath);

            // Если текущая директория — корневая, возвращаем null
            if ($parentPath === $this->rootDir) {
                return null;
            }

            return $parentPath;
        }

        public function getFilesAndFolders($path = null) {
            $path = $path ?: $this->currentPath;

            if (!is_dir($path)) {
                return [];
            }

            $items = scandir($path);
            $result = [];

            foreach ($items as $item) {
                if ($item === '.' || $item === '..') continue;
                $fullPath = $path . '/' . $item;

                $extension = pathinfo($_SERVER["DOCUMENT_ROOT"] . "/" . $fullPath, PATHINFO_EXTENSION);
                if ($extension == "metadata") {
                    continue;
                }

                $reservedNames = getReservedFMNames();
                $reservedExtensions = getReservedFMExtensions();
                $continue = false;
                foreach ($reservedNames as $reservedName) {
                    if ($item == $reservedName) {
                        $continue = true;
                    }
                }
                foreach ($reservedExtensions as $reservedExtension) {
                    if ($extension == $reservedExtension) {
                        $continue = true;
                    }
                }
                if ($continue) {
                    continue;
                }

                $permissions = $this->getFormattedPermissions($fullPath);

                if (is_file($fullPath)) {
                    $fileSize = filesize($fullPath);
                    $fileSizeInMB = $fileSize / 1024 / 1024;
                    $fileSizeInKB = $fileSize / 1024;
                } else {
                    $fileSizeInMB = 0;
                    $fileSizeInKB = 0;
                    $fileSize = 0;
                }

                $result[] = [
                    'extension' => $extension,
                    'size' => $fileSizeInMB > 1
                        ? number_format($fileSizeInMB, 2) . " MB"
                        : ($fileSizeInKB >= 1
                            ? number_format($fileSizeInKB, 2) . " KB"
                            : ($fileSize > 0
                                ? $fileSize . " байт"
                                : "Папка")),
                    'full_path' => $fullPath,
                    'name' => $item,
                    'is_dir' => is_dir($fullPath),
                    'permissions' => $permissions,
                    'normal_path' => str_replace($this->rootDir . "/", "", $fullPath) != "uploads"
                        ? str_replace($this->rootDir . "/", "", $fullPath)
                        : $item
                ];
            }
            return $result;
        }

        private function getFormattedPermissions($filePath) {
            $perms = fileperms($filePath);

            // Определяем тип файла
            switch ($perms & 0xF000) {
                case 0xC000: $type = 's'; break; // Сокет
                case 0xA000: $type = 'l'; break; // Символическая ссылка
                case 0x8000: $type = '-'; break; // Обычный файл
                case 0x6000: $type = 'b'; break; // Блочное устройство
                case 0x4000: $type = 'd'; break; // Каталог
                case 0x2000: $type = 'c'; break; // Символьное устройство
                case 0x1000: $type = 'p'; break; // Канал FIFO
                default:     $type = 'u'; break; // Неизвестный тип
            }

            // Права для владельца
            $owner = (($perms & 0x0100) ? 'r' : '-') .
                (($perms & 0x0080) ? 'w' : '-') .
                (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x') : (($perms & 0x0800) ? 'S' : '-'));

            // Права для группы
            $group = (($perms & 0x0020) ? 'r' : '-') .
                (($perms & 0x0010) ? 'w' : '-') .
                (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x') : (($perms & 0x0400) ? 'S' : '-'));

            // Права для остальных
            $others = (($perms & 0x0004) ? 'r' : '-') .
                (($perms & 0x0002) ? 'w' : '-') .
                (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x') : (($perms & 0x0200) ? 'T' : '-'));

            return $type . $owner . $group . $others;
        }

        public function createFolder($name) {
            $newDir = $this->currentPath . '/' . $name;
            if (!file_exists($newDir)) {
                mkdir($newDir);
            }
        }

        public function uploadFile($file) {
            move_uploaded_file($file['tmp_name'], $this->currentPath . '/' . $file['name']);
        }

        public function renameItem($oldName, $newName) {
            rename($this->currentPath . '/' . $oldName, $this->currentPath . '/' . $newName);
        }

        public function deleteItem($name) {
            $itemPath = $this->currentPath . '/' . $name;
            if (is_dir($itemPath)) {
                rmdir($itemPath);
            } else {
                unlink($itemPath);
            }
        }
    }

    $fileManager = new FileManager($db_connect);

    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $action = $_POST['action'];
        switch ($action) {
            case 'create_folder':
                $fileManager->createFolder($_POST['name']);
                break;
            case 'upload_file':
                $fileManager->uploadFile($_FILES['file']);
                break;
            case 'rename_item':
                $fileManager->renameItem($_POST['old_name'], $_POST['new_name']);
                break;
            case 'delete_item':
                $fileManager->deleteItem($_POST['name']);
                break;
        }

        header("Location: admin.php?action=file-management&path=" . urlencode($_GET['path'] ?? ''));
        exit;
    }

    $files = $fileManager->getFilesAndFolders();
    $parentPath = $fileManager->getParentPath();
    if ($fileManager->getCurrentPath(true) === '') { // Если текущая директория — корневая
        $parentPath = null;
    }

    usort($files, function ($a, $b) {
        if ($a["size"] === "Папка" && $b["size"] !== "Папка") {
            return -1; // "Папка" идёт первой
        }
        if ($a["size"] !== "Папка" && $b["size"] === "Папка") {
            return 1; // "Файл" идёт после "Папка"
        }
        return strcmp($a["name"], $b["name"]); // Алфавитная сортировка
    });

    function getDirectoryStats($directory) {
        if (!is_dir($directory)) {
            return [];
        }

        $fileCount = 0;
        $folderCount = 0;
        $totalSize = 0;

         try {
            $directoryIterator = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS),
                RecursiveIteratorIterator::SELF_FIRST
            );

            foreach ($directoryIterator as $fileinfo) {
                if ($fileinfo->isFile()) {
                    $fileCount++;
                    $totalSize += $fileinfo->getSize();
                } elseif ($fileinfo->isDir()) {
                    $folderCount++;
                }
            }
        } catch (Exception $e) {
            error_log("Ошибка при анализе директории: " . $e->getMessage());
            return ['folders' => 0, 'files' => 0, 'size' => 0];
        }
        $totalSizeMB = $totalSize / 1024 / 1024;

        // Возвращаем результаты
        return [
            'folders' => $folderCount,
            'files' => $fileCount,
            'total_size' => number_format($totalSizeMB, 2)
        ];
    }

    // Пример использования
    if (isset($_GET["path"])) {
        $directory = $_SERVER["DOCUMENT_ROOT"]."/".$_GET['path'];  // Замените на вашу директорию
        $pathParts = explode('/', $_GET['path']);
    } else {
        $directory = $_SERVER["DOCUMENT_ROOT"];
        $pathParts = ["Корневая"];
    }

    $stats = getDirectoryStats($directory);

    array_pop($pathParts);

    $pathWithoutLast = implode('/', $pathParts);
    $smarty->assign('pathWithoutLast', $pathWithoutLast);
    $smarty->assign('stats', $stats);
    $smarty->assign('files', $files);
    $smarty->assign('currentPath', $fileManager->getCurrentPath(true)); // Относительный путь
    $smarty->assign('parentPath', $parentPath ? str_replace($fileManager->rootDir . '/', '', $parentPath) : null);

    $yourData = array('title' => $lang['nav']['filemanagement'] . ' - ' . $config['title']);
    $smarty->assign('data', $yourData);
    $smarty->assign('page_name', '
        <li class="breadcrumb-item active">' . $lang['nav']['filemanagement'] . '</li>
    ');
    $smarty->assign('theme', SYSTEM_DIR);
    $smarty->assign('config', $config);