<script lang="ts">
import { onMount } from 'svelte';
import { page } from '$app/stores';
import { Button } from '$lib/components/ui/button';
import { Input } from '$lib/components/ui/input';
import { Label } from '$lib/components/ui/label';
import { Card, CardContent, CardHeader, CardTitle } from '$lib/components/ui/card';
import { goto } from '$app/navigation';
import { get } from 'svelte/store';
import FileBrowser from './FileBrowser.svelte';

let experimentId = '';
let experiment: any = null;
let name = '';
let description = '';
let error = '';
let success = '';
let files: any[] = [];
let uploading = false;
let uploadError = '';
let copied = false;
let origin = '';

async function fetchFiles() {
  if (!experimentId) return;
  console.log('fetchFiles called for experimentId:', experimentId);
  const res = await fetch(`/api/experiment/${experimentId}/files`);
  if (res.ok) {
    const data = await res.json();
    console.log('fetchFiles response:', data);
    files = data.files;
  } else {
    console.log('fetchFiles failed:', res.status);
  }
}

async function handleFileInput(event: Event) {
  const input = event.target as HTMLInputElement;
  if (input.files) await uploadFiles(input.files);
}

async function uploadFiles(fileList: FileList) {
  uploading = true;
  uploadError = '';
  try {
    for (const file of Array.from(fileList)) {
      const form = new FormData();
      form.append('file', file);
      // Use webkitRelativePath if present, else fallback to file.name
      form.append('relativePath', file.webkitRelativePath || file.name);
      const res = await fetch(`/api/experiment/${experimentId}/files`, {
        method: 'POST',
        body: form,
      });
      if (!res.ok) {
        const data = await res.json().catch(() => ({}));
        throw new Error(data.error || 'Upload failed');
      }
    }
    await fetchFiles();
  } catch (e: any) {
    uploadError = e.message || 'Upload failed';
  } finally {
    uploading = false;
  }
}

async function deleteFile(key: string) {
  const url = `/api/experiment/${experimentId}/files?key=${encodeURIComponent(key)}`;
  const res = await fetch(url, { method: 'DELETE' });
  if (res.ok) await fetchFiles();
}

// Helper: Convert flat file list to tree
function buildFileTree(files: any[]): any {
  const root: any = {};
  for (const file of files) {
    const parts = file.name.split('/');
    let node = root;
    for (let i = 0; i < parts.length; i++) {
      const part = parts[i];
      if (!part) continue;
      if (i === parts.length - 1) {
        // File
        node[part] = { ...file, isFile: true };
      } else {
        // Folder
        node[part] = node[part] || { children: {}, isFile: false };
        node = node[part].children;
      }
    }
  }
  return root;
}

let expanded = new Set<string>();
function toggleFolder(path: string) {
  if (expanded.has(path)) expanded.delete(path);
  else expanded.add(path);
  expanded = new Set(expanded); // trigger reactivity
}

function copyLink() {
  const link = `${origin}/public/run/${experiment.id}`;
  navigator.clipboard.writeText(link);
  copied = true;
  setTimeout(() => (copied = false), 2000);
}

async function deleteFileOrFolder(key: string, isFolder: boolean) {
  console.log('deleteFileOrFolder called:', { key, isFolder, experimentId });
  // If folder, send a delete request with a prefix param
  if (isFolder) {
    const url = `/api/experiment/${experimentId}/files?prefix=${encodeURIComponent(key)}`;
    console.log('Deleting folder with URL:', url);
    const res = await fetch(url, { method: 'DELETE' });
    console.log('Folder delete response:', res.status, res.ok);
    if (res.ok) await fetchFiles();
  } else {
    console.log('Deleting file with key:', key);
    await deleteFile(key);
  }
}

onMount(async () => {
  origin = window.location.origin;
  const params = get(page).params;
  experimentId = params.id;
  const res = await fetch(`/api/experiment?id=${experimentId}`);
  if (res.ok) {
    const data = await res.json();
    experiment = data.experiment;
    console.log(experiment)
    name = experiment.name;
    description = experiment.description;
  } else {
    error = 'Failed to load experiment.';
  }
  await fetchFiles();
});

async function handleSave() {
  error = '';
  success = '';
  const res = await fetch(`/api/experiment?id=${experimentId}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ name, description })
  });
  if (res.ok) {
    success = 'Experiment updated!';
  } else {
    error = 'Failed to update experiment.';
  }
}
</script>

{#if experiment}
  <div class="flex flex-col min-h-screen bg-background py-8">
    <Card class="mb-8 w-full max-w-xl mx-auto">
      <CardHeader>
        <CardTitle>Experiment Details</CardTitle>
      </CardHeader>
      <CardContent>
        <div class="mb-4">
          <Label>ID</Label>
          <div class="text-sm text-muted-foreground mb-2">{experiment.id}</div>
        </div>
        <form on:submit|preventDefault={handleSave} class="space-y-4">
          <div>
            <Label for="name">Name</Label>
            <Input id="name" type="text" bind:value={name} required />
          </div>
          <div>
            <Label for="description">Description</Label>
            <Input id="description" type="text" bind:value={description} />
          </div>
          <div>
            <Label>Created At</Label>
            <div class="text-sm text-muted-foreground mb-2">{new Date(experiment.createdAt).toLocaleString()}</div>
          </div>
          {#if error}
            <div class="text-red-500 text-sm">{error}</div>
          {/if}
          {#if success}
            <div class="text-green-600 text-sm">{success}</div>
          {/if}
          <Button type="submit">Save Changes</Button>
        </form>
      </CardContent>
    </Card>

    <Card class="mb-8 w-full max-w-xl mx-auto">
      <CardHeader>
        <CardTitle>Public Link</CardTitle>
      </CardHeader>
      <CardContent>
        <p class="text-sm text-muted-foreground mb-2">
          Share this link with your participants to run the experiment.
        </p>
        <div class="flex items-center space-x-2">
          <Input id="public-link" type="text" readonly value="{`${origin}/public/run/${experiment.id}`}" />
          <Button on:click={copyLink}>Copy</Button>
        </div>
        {#if copied}
          <p class="text-green-600 text-sm mt-2">Copied to clipboard!</p>
        {/if}
      </CardContent>
    </Card>
    
    <Card class="w-full max-w-xl mx-auto">
      <CardHeader>
        <CardTitle>Experiment Files</CardTitle>
      </CardHeader>
      <CardContent>
        <div class="mt-8">
          <Label>Experiment Files</Label>
          <div
            class="border-2 border-dashed rounded-md p-4 mb-4 text-center cursor-pointer bg-muted hover:bg-accent transition"
            on:click={() => document.getElementById('file-input')?.click()}
          >
            <div>Click to select files or a folder to upload (folder structure will be preserved)</div>
            <input id="file-input" type="file" multiple webkitdirectory class="hidden" on:change={handleFileInput} />
          </div>
          {#if uploading}
            <div class="text-blue-600 text-sm mb-2">Uploading...</div>
          {/if}
          {#if uploadError}
            <div class="text-red-500 text-sm mb-2">{uploadError}</div>
          {/if}
          <ul class="divide-y divide-border">
            <FileBrowser
              tree={buildFileTree(files)}
              parentPath=""
              {expanded}
              onToggle={toggleFolder}
              onDelete={deleteFileOrFolder}
            />
            {#if files.length === 0}
              <li class="text-muted-foreground text-sm py-2">No files uploaded yet.</li>
            {/if}
          </ul>
        </div>
      </CardContent>
    </Card>
  </div>
{:else if error}
  <div class="flex justify-center items-center min-h-screen bg-background">
    <Card class="w-full max-w-md">
      <CardHeader>
        <CardTitle>Error</CardTitle>
      </CardHeader>
      <CardContent>
        <div class="text-red-500">{error}</div>
      </CardContent>
    </Card>
  </div>
{:else}
  <div class="flex justify-center items-center min-h-screen bg-background">
    <div>Loading...</div>
  </div>
{/if} 