<!-- #region StorageIndexPage [C:3] [TYPE Page] [SEMANTICS sveltekit, storage, file, upload, management] -->
<!-- @BRIEF Page component: routes/tools/storage/+page.svelte -->
<!-- @LAYER Page -->
<!--
@UX_STATE: Loading -> Default

@SEMANTICS: storage, file, upload, management
@PURPOSE:   Main page for unified file storage management.
@LAYER     UI
@RELATION  DEPENDS_ON -> [storageService]
@RELATION  CONTAINS -> [FileList]
@RELATION  CONTAINS -> [FileUpload]

@INVARIANT: Always displays a unified storage view without category tabs.
-->

<script lang="ts">
  // [SECTION: IMPORTS]
  import { onMount } from 'svelte';
  import { page } from '$app/state';
  import { listFiles, deleteFile } from '../../../services/storageService';
  import { addToast } from '$lib/toasts.svelte.js';
  import { t } from '$lib/i18n/index.svelte.js';
  import FileList from '../../../components/storage/FileList.svelte';
  import FileUpload from '../../../components/storage/FileUpload.svelte';
  // [/SECTION: IMPORTS]

  // #region loadFiles:Function [TYPE Function]
  /**
   * @purpose Fetches the list of files from the server.
   * @pre     currentPath is a valid storage path or empty for root.
   * @post    Updates the `files` array with the latest data.
   */
  let files = $state([]);
  let isLoading = $state(false);
  let currentPath = $state('');

  // #region resolveStorageQueryFromPath:Function [TYPE Function]
  /**
   * @purpose Splits UI path into storage API category and category-local subpath.
   * @pre     uiPath may be empty or start with backups/repositorys.
   * @post    Returns {category, subpath} compatible with /api/storage/files.
   */
  function resolveStorageQueryFromPath(uiPath: string): { category?: string; subpath?: string } {
    const segments = String(uiPath || '').split('/').filter(Boolean);
    if (segments.length === 0) return {};
    const topLevel = segments[0];
    if (topLevel !== 'backups' && topLevel !== 'repositorys') {
      return {};
    }
    const subpath = segments.slice(1).join('/');
    return {
      category: topLevel,
      subpath: subpath || undefined,
    };
  }
  // #endregion resolveStorageQueryFromPath:Function

  async function loadFiles() {
    console.log('[STORAGE-PAGE][LOAD_START] path=%s', currentPath);
    isLoading = true;
    try {
      const query = resolveStorageQueryFromPath(currentPath);
      files = await listFiles(query.category, query.subpath);
      console.log('[STORAGE-PAGE][LOAD_OK] count=%d', files.length);
    } catch (error) {
      console.log('[STORAGE-PAGE][LOAD_ERR] error=%s', error.message);
      addToast($t.storage.messages.load_failed.replace('{error}', error.message), 'error');
    } finally {
      isLoading = false;
    }
  }
  // #endregion loadFiles:Function

  // #region handleDelete:Function [TYPE Function]
  /**
   * @purpose Handles the file deletion process.
   * @pre     The event contains valid category and path.
   * @post    File is deleted and file list is refreshed.
   * @param   {CustomEvent} event - The delete event containing category and path.
   */
  async function handleDelete(payload) {
    const { category, path, name } = payload || {};
    if (!category || !path || !name) {
      console.warn('[STORAGE-PAGE][DELETE_SKIP] invalid payload', payload);
      return;
    }
    console.log('[STORAGE-PAGE][DELETE_START] category=%s path=%s', category, path);
    if (!confirm($t.storage.messages.delete_confirm.replace('{name}', name))) return;

    try {
      await deleteFile(category, path);
      console.log('[STORAGE-PAGE][DELETE_OK] name=%s', name);
      addToast($t.storage.messages.delete_success.replace('{name}', name), 'success');
      await loadFiles();
    } catch (error) {
      console.log('[STORAGE-PAGE][DELETE_ERR] error=%s', error.message);
      addToast($t.storage.messages.delete_failed.replace('{error}', error.message), 'error');
    }
  }
  // #endregion handleDelete:Function

  // #region handleNavigate:Function [TYPE Function]
  /**
   * @purpose Updates the current path and reloads files when navigating into a directory.
   * @pre     The event contains a valid path string.
   * @post    currentPath is updated and files are reloaded.
   * @param   {CustomEvent} event - The navigation event containing the new path.
   */
  function handleNavigate(path) {
    if (!path || typeof path !== 'string') {
      console.warn('[STORAGE-PAGE][NAVIGATE_SKIP] invalid path', path);
      return;
    }
    console.log('[STORAGE-PAGE][NAVIGATE] path=%s', path);
    currentPath = path;
    loadFiles();
  }
  // #endregion handleNavigate:Function

  // #region navigateUp:Function [TYPE Function]
  /**
   * @purpose Navigates one level up in the directory structure.
   * @pre     currentPath is not root.
   * @post    currentPath is moved up one directory level.
   */
  function navigateUp() {
    if (!currentPath) return;
    const parts = currentPath.split('/');
    parts.pop();
    currentPath = parts.join('/') || '';
    loadFiles();
  }
  // #endregion navigateUp:Function

  // #region updateUploadCategory:Function [TYPE Function]
  /**
   * @purpose Keeps upload category aligned with the currently viewed top-level folder.
   * @pre     currentPath can be empty or a slash-delimited path.
   * @post    uploadCategory is either backups or repositorys.
   */
  let uploadCategory = $derived(
    currentPath.split('/').filter(Boolean)[0] === 'repositorys'
      ? 'repositorys'
      : 'backups',
  );
  let uploadSubpath = $derived.by(() => {
    const [topLevel, ...rest] = currentPath.split('/').filter(Boolean);
    return topLevel === 'repositorys' || topLevel === 'backups'
      ? rest.join('/')
      : '';
  });
  // #endregion updateUploadCategory:Function

  onMount(() => {
    const pathParam = page.url.searchParams.get('path');
    if (pathParam) {
      currentPath = pathParam;
    }
    loadFiles();
  });
</script>

<!-- [SECTION: TEMPLATE] -->
<div class="container mx-auto w-full p-4 min-[1280px]:max-w-[1400px] min-[1536px]:max-w-[1680px]">
  <div class="mb-6">
    <h1 class="text-2xl font-bold text-gray-900">{$t.storage.management}</h1>
    <div class="flex items-center mt-2 text-sm text-gray-500">
      <button onclick={() => { currentPath = ''; loadFiles(); }} class="hover:text-indigo-600">{$t.storage.root}</button>
      {#each currentPath.split('/').filter(Boolean) as part, i}
          <span class="mx-2">/</span>
          <button
            onclick={() => {
              currentPath = currentPath.split('/').filter(Boolean).slice(0, i + 1).join('/');
              loadFiles();
            }}
            class="hover:text-indigo-600 capitalize"
          >
            {part}
          </button>
      {/each}
    </div>
  </div>

  <div class="flex justify-end mb-4">
    <button
      onclick={loadFiles}
      class="inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50"
      disabled={isLoading}
    >
      {isLoading ? $t.storage.refreshing : $t.storage.refresh}
    </button>
  </div>

  <div class="grid grid-cols-1 xl:grid-cols-[minmax(0,1fr)_360px] 2xl:grid-cols-[minmax(0,1fr)_420px] gap-6">
    <!-- Main Content: File List -->
    <div class="space-y-4 min-w-0">
      <div class="flex items-center mb-2">
        {#if currentPath}
          <button
            onclick={navigateUp}
            class="mr-4 inline-flex items-center px-3 py-1 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50"
          >
            <svg class="h-4 w-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
            </svg>
            {$t.common?.back}
          </button>
        {/if}
      </div>

      <FileList {files} ondelete={handleDelete} onnavigate={handleNavigate} />
    </div>

    <!-- Sidebar: Upload -->
    <div class="lg:col-span-1">
      <FileUpload
        category={uploadCategory}
        path={uploadSubpath}
        onuploaded={loadFiles}
      />
    </div>
  </div>
</div>
<!-- [/SECTION: TEMPLATE] -->


<!-- #endregion StorageIndexPage -->
