<?php
/**
 * Flexia disk — carpeta de recuperación tras formateo, visible en Mis documentos del administrador.
 */

if (!defined('GRID_FLEXIA_DISK_DIRNAME')) {
    define('GRID_FLEXIA_DISK_DIRNAME', 'flexia disk');
}

if (!function_exists('grid_flexia_disk_root_abs')) {
    function grid_flexia_disk_root_abs(): string
    {
        $root = defined('GRID_ROOT') && is_string(GRID_ROOT) && GRID_ROOT !== ''
            ? GRID_ROOT
            : (defined('ANTARA_ROOT') ? ANTARA_ROOT : dirname(__DIR__));

        return $root . DIRECTORY_SEPARATOR . GRID_FLEXIA_DISK_DIRNAME;
    }
}

if (!function_exists('grid_flexia_disk_resolved_root')) {
    /**
     * @return string|false realpath de la raíz flexia disk
     */
    function grid_flexia_disk_resolved_root()
    {
        grid_flexia_disk_ensure_root_exists();
        $rp = realpath(grid_flexia_disk_root_abs());

        return ($rp !== false && is_dir($rp)) ? $rp : false;
    }
}

if (!function_exists('grid_flexia_disk_ensure_root_exists')) {
    function grid_flexia_disk_ensure_root_exists(): void
    {
        $path = grid_flexia_disk_root_abs();
        if (!is_dir($path)) {
            @mkdir($path, 0755, true);
        }
    }
}

if (!function_exists('grid_flexia_disk_has_backups')) {
    function grid_flexia_disk_has_backups(): bool
    {
        $root = grid_flexia_disk_resolved_root();
        if ($root === false) {
            return false;
        }
        $items = @scandir($root);
        if (!is_array($items)) {
            return false;
        }
        foreach ($items as $it) {
            if ($it !== '.' && $it !== '..') {
                return true;
            }
        }

        return false;
    }
}

if (!function_exists('grid_flexia_disk_admin_link_path')) {
    function grid_flexia_disk_admin_link_path(string $userId): string
    {
        if (!function_exists('grid_user_explorer_files_dir')) {
            require_once __DIR__ . '/user_settings_helpers.php';
        }

        return grid_user_explorer_files_dir($userId) . DIRECTORY_SEPARATOR . GRID_FLEXIA_DISK_DIRNAME;
    }
}

if (!function_exists('grid_flexia_disk_remove_link_or_empty_dir')) {
    function grid_flexia_disk_remove_link_or_empty_dir(string $path): void
    {
        if (!file_exists($path)) {
            return;
        }
        require_once __DIR__ . '/path_security.php';
        if (grid_path_is_reparse_or_link($path) || is_link($path)) {
            if (is_dir($path)) {
                @rmdir($path);
            } else {
                @unlink($path);
            }

            return;
        }
        if (!is_dir($path)) {
            @unlink($path);

            return;
        }
        $items = @scandir($path);
        if (!is_array($items)) {
            return;
        }
        if (count(array_diff($items, ['.', '..'])) === 0) {
            @rmdir($path);
        }
    }
}

if (!function_exists('grid_flexia_disk_link_points_to_target')) {
    function grid_flexia_disk_link_points_to_target(string $linkPath, string $targetPath): bool
    {
        if (!file_exists($linkPath)) {
            return false;
        }
        require_once __DIR__ . '/path_security.php';
        $linkReal = realpath($linkPath);
        $targetReal = realpath($targetPath);
        if ($linkReal === false || $targetReal === false) {
            return false;
        }

        return $linkReal === $targetReal
            || grid_path_is_same_or_under($linkReal, $targetReal)
            || grid_path_is_same_or_under($targetReal, $linkReal);
    }
}

if (!function_exists('grid_flexia_disk_create_directory_link')) {
    function grid_flexia_disk_create_directory_link(string $linkPath, string $targetPath): bool
    {
        require_once __DIR__ . '/path_security.php';
        grid_flexia_disk_ensure_root_exists();
        $targetReal = realpath($targetPath);
        if ($targetReal === false || !is_dir($targetReal)) {
            return false;
        }

        $parent = dirname($linkPath);
        if (!is_dir($parent) && !@mkdir($parent, 0755, true)) {
            return false;
        }

        if (grid_flexia_disk_link_points_to_target($linkPath, $targetReal)) {
            return true;
        }

        grid_flexia_disk_remove_link_or_empty_dir($linkPath);

        if (grid_path_is_windows()) {
            $cmds = [
                'cmd /c mklink /J ' . escapeshellarg($linkPath) . ' ' . escapeshellarg($targetReal),
                'powershell -NoProfile -ExecutionPolicy Bypass -Command '
                    . escapeshellarg('New-Item -ItemType Junction -Force -Path '
                        . $linkPath . ' -Target ' . $targetReal),
            ];
            foreach ($cmds as $cmd) {
                $lines = [];
                $code = 1;
                @exec($cmd, $lines, $code);
                if ($code === 0 && is_dir($linkPath) && grid_flexia_disk_link_points_to_target($linkPath, $targetReal)) {
                    return true;
                }
            }

            $linkDir = dirname($linkPath);
            $relTarget = basename($targetReal);
            $up = 0;
            $probe = $linkDir;
            $root = dirname($targetReal);
            while ($up < 12 && $probe !== dirname($probe)) {
                if (realpath($probe) === realpath($root)) {
                    break;
                }
                $relTarget = '..' . DIRECTORY_SEPARATOR . $relTarget;
                $up++;
                $probe = dirname($probe);
            }
            $cmdRel = 'cmd /c mklink /J ' . escapeshellarg($linkPath) . ' ' . escapeshellarg($relTarget);
            $lines = [];
            $code = 1;
            $oldCwd = getcwd();
            if ($oldCwd !== false && @chdir($linkDir)) {
                @exec($cmdRel, $lines, $code);
                @chdir($oldCwd);
            }
            if ($code === 0 && is_dir($linkPath) && grid_flexia_disk_link_points_to_target($linkPath, $targetReal)) {
                return true;
            }
        }

        if (@symlink($targetReal, $linkPath)) {
            return true;
        }

        return is_dir($linkPath) && grid_flexia_disk_link_points_to_target($linkPath, $targetReal);
    }
}

if (!function_exists('grid_flexia_disk_normalize_rel_path')) {
    /**
     * @return array{0: string, 1: list<string>} [rel web, partes seguras]
     */
    function grid_flexia_disk_normalize_rel_path(string $relPath): array
    {
        $relPath = str_replace(['\\', "\0"], ['/', ''], $relPath);
        $relPath = ltrim($relPath, '/');
        $parts = array_values(array_filter(explode('/', $relPath), static function ($p) {
            return $p !== '' && $p !== '.' && $p !== '..';
        }));

        return [implode('/', $parts), $parts];
    }
}

if (!function_exists('grid_flexia_disk_virtual_files_context')) {
    /**
     * Si la ruta personal empieza por flexia disk/, resuelve contra la carpeta de respaldo en la raíz del proyecto.
     *
     * @param array{id?: string, role?: string} $actor
     * @return array{baseDir: string, urlPrefix: string, innerRel: string}|null
     */
    function grid_flexia_disk_virtual_files_context(string $relPath, array $actor): ?array
    {
        if (!function_exists('grid_explorer_shared_is_admin_role')) {
            require_once __DIR__ . '/explorer_shared_spaces.php';
        }
        if (!grid_explorer_shared_is_admin_role((string) ($actor['role'] ?? ''))) {
            return null;
        }

        [, $parts] = grid_flexia_disk_normalize_rel_path($relPath);
        if ($parts === [] || $parts[0] !== GRID_FLEXIA_DISK_DIRNAME) {
            return null;
        }

        array_shift($parts);
        $root = grid_flexia_disk_resolved_root();
        if ($root === false) {
            return null;
        }

        $innerRel = implode(DIRECTORY_SEPARATOR, $parts);
        $baseDir = $innerRel !== '' ? $root . DIRECTORY_SEPARATOR . $innerRel : $root;
        if (!is_dir($baseDir)) {
            return null;
        }

        $urlInner = $innerRel !== '' ? str_replace(DIRECTORY_SEPARATOR, '/', $innerRel) . '/' : '';

        return [
            'baseDir' => $baseDir,
            'urlPrefix' => GRID_FLEXIA_DISK_DIRNAME . '/' . $urlInner,
            'innerRel' => $innerRel,
        ];
    }
}

if (!function_exists('grid_flexia_disk_files_storage_context')) {
    /**
     * @param array<string, mixed> $input
     * @param array{id?: string, role?: string} $actor
     * @return array{ok: bool, bucket: string, departmentId: string, baseDir: string, urlPrefix: string}
     */
    function grid_flexia_disk_files_storage_context(array $input, array $actor): array
    {
        if (!function_exists('grid_explorer_local_files_base')) {
            require_once __DIR__ . '/user_settings_helpers.php';
        }

        $path = isset($input['path']) ? (string) $input['path'] : '';
        grid_flexia_disk_ensure_admin_explorer_link(
            isset($actor['id']) ? (string) $actor['id'] : null,
            isset($actor['role']) ? (string) $actor['role'] : null
        );

        $virtual = grid_flexia_disk_virtual_files_context($path, $actor);
        if ($virtual !== null) {
            return [
                'ok' => true,
                'bucket' => 'files',
                'departmentId' => '',
                'baseDir' => $virtual['baseDir'],
                'urlPrefix' => $virtual['urlPrefix'],
            ];
        }

        return [
            'ok' => true,
            'bucket' => 'files',
            'departmentId' => '',
            'baseDir' => grid_explorer_local_files_base(),
            'urlPrefix' => grid_explorer_local_url_prefix('files'),
        ];
    }
}

if (!function_exists('grid_flexia_disk_append_root_listing_entry')) {
    /**
     * Añade «flexia disk» al listado raíz de Mis documentos si hay respaldos y no aparece ya.
     *
     * @param list<array<string, mixed>> $items
     * @return list<array<string, mixed>>
     */
    function grid_flexia_disk_append_root_listing_entry(array $items, string $safeRelPath, array $actor, string $urlPrefix): array
    {
        if ($safeRelPath !== '') {
            return $items;
        }
        if (!function_exists('grid_explorer_shared_is_admin_role')) {
            require_once __DIR__ . '/explorer_shared_spaces.php';
        }
        if (!grid_explorer_shared_is_admin_role((string) ($actor['role'] ?? ''))) {
            return $items;
        }
        if (!grid_flexia_disk_has_backups()) {
            return $items;
        }
        foreach ($items as $it) {
            if (isset($it['name']) && (string) $it['name'] === GRID_FLEXIA_DISK_DIRNAME) {
                return $items;
            }
        }
        $root = grid_flexia_disk_resolved_root();
        if ($root === false) {
            return $items;
        }
        $items[] = [
            'name' => GRID_FLEXIA_DISK_DIRNAME,
            'type' => 'dir',
            'mimeType' => '',
            'size' => 0,
            'mtime' => filemtime($root) ?: time(),
            'path' => '',
            'url' => GRID_FLEXIA_DISK_DIRNAME . '/',
        ];

        return $items;
    }
}

if (!function_exists('grid_flexia_disk_ensure_admin_explorer_link')) {
    /**
     * Enlaza flexia disk dentro de Mis documentos (media/explorer/users/{id}/files/) para super_admin y admin.
     */
    function grid_flexia_disk_ensure_admin_explorer_link(?string $userId = null, ?string $role = null): void
    {
        if (!function_exists('grid_explorer_shared_is_admin_role')) {
            require_once __DIR__ . '/explorer_shared_spaces.php';
        }
        if (!function_exists('grid_user_explorer_files_dir')) {
            require_once __DIR__ . '/user_settings_helpers.php';
        }

        if ($userId === null && function_exists('grid_explorer_session_user_id')) {
            $userId = grid_explorer_session_user_id();
        }
        if ($userId === null || $userId === '') {
            return;
        }

        if ($role === null || $role === '') {
            if (!class_exists('AntaraStore', false)) {
                require_once dirname(__DIR__) . '/core/auth/store.php';
            }
            $fresh = AntaraStore::findUserById($userId);
            $role = is_array($fresh) ? (string) ($fresh['role'] ?? '') : '';
        }

        if (!grid_explorer_shared_is_admin_role($role)) {
            return;
        }

        foreach ([grid_user_explorer_files_dir($userId), grid_user_explorer_trash_dir($userId)] as $dir) {
            if (!is_dir($dir)) {
                @mkdir($dir, 0755, true);
            }
        }

        if (!grid_flexia_disk_has_backups()) {
            return;
        }

        $target = grid_flexia_disk_root_abs();
        $linkPath = grid_flexia_disk_admin_link_path($userId);

        if (grid_flexia_disk_link_points_to_target($linkPath, $target)) {
            return;
        }

        if (is_dir($linkPath) && !grid_flexia_disk_create_directory_link($linkPath, $target)) {
            $items = @scandir($linkPath);
            $hasContent = is_array($items) && count(array_diff($items, ['.', '..'])) > 0;
            if (!$hasContent) {
                grid_flexia_disk_remove_link_or_empty_dir($linkPath);
                grid_flexia_disk_create_directory_link($linkPath, $target);
            }
        } else {
            grid_flexia_disk_create_directory_link($linkPath, $target);
        }
    }
}
