<script>
  import { Copy, RotateCcw, Play, Download, Share, Pause, Layout, Code } from 'lucide-svelte';
  import { onMount } from 'svelte';
  import Prism from 'prismjs';
  import 'prismjs/components/prism-python';
  import 'prismjs/components/prism-bash';
  import Navbar from '$lib/components/Navbar.svelte';

  let selectedModel = 'Chatterbox';
  let mode = 'api';
  let codeHistory = [];
  let setupCode = generateSetupCode();
  let importCode = generateImportCode();
  let copyNotification = null;
  let historyCount = 0;

  const models = [
    { id: 'chatterbox', name: 'Chatterbox', badge: 'recommended' },
    { id: 'kokoro', name: 'Kokoro', badge: 'coming soon', disabled: true },
  ];

  const voices = [
    {
      id: 'andrew',
      name: 'Andrew',
      description: 'Older British man who speaks clearly and kindly',
      sample: '/voices/andrew.mp3',
      preview_url:
        'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/andrew.mp3',
    },
    {
      id: 'lily',
      name: 'Jasmine',
      description: 'Warm, conversational tone of a woman in her 30s',
      sample: '/voices/lily.mp3',
      preview_url:
        'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/lily.mp3',
    },
    {
      id: 'pirate',
      name: 'Pirate',
      description: 'Young male pirate-y voice that speaks gruffly and with excitement',
      sample: '/voices/pirate.mp3',
      preview_url:
        'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/pirate.mp3',
    },
    {
      id: 'fairy',
      name: 'Fairy',
      description: 'High and airy female voice that bursts with excitement',
      sample: '/voices/fairy.mp3',
      preview_url:
        'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/fairy.mp3',
    },
  ];

  async function loadHistoryFromDatabase() {
    try {
      const response = await fetch('/api/history/load', {
        method: 'GET',
        credentials: 'include',
      });

      if (response.ok) {
        const data = await response.json();

        const setupEntries = data.entries.filter((e) => e.entry_type === 'setup');
        const importEntries = data.entries.filter((e) => e.entry_type === 'import');
        const generationEntries = data.entries.filter((e) => e.entry_type === 'generation');

        setupCode = generateSetupCode();
        importCode =
          importEntries.length > 0
            ? importEntries[importEntries.length - 1].code
            : generateImportCode();

        codeHistory = generationEntries.map((entry) => ({
          id: entry.id,
          code: entry.code,
          result: entry.result_data,
        }));

        historyCount = generationEntries.length;
      }
    } catch (error) {
      console.error('Error loading history from database:', error);
      codeHistory = [];
      setupCode = generateSetupCode();
      importCode = generateImportCode();
    }
  }

  async function resetHistory() {
    try {
      await fetch('/api/history/clear', {
        method: 'DELETE',
        credentials: 'include',
      });

      codeHistory = [];
      setupCode = generateSetupCode();
      importCode = generateImportCode();
      historyCount = 0;
    } catch (error) {
      console.error('Error clearing history:', error);
      codeHistory = [];
      setupCode = generateSetupCode();
      importCode = generateImportCode();
      historyCount = 0;
    }
  }

  function generateSetupCode() {
    if (mode === 'local') {
      return `pip install huggingface-hub hfstudio uv
hfstudio start ${selectedModel.toLowerCase()} --port 7861`;
    } else {
      return `pip install huggingface-hub`;
    }
  }

  function generateClientInitCode() {
    if (mode === 'local') {
      const port = 7861;
      return `client = InferenceClient(base_url="http://localhost:${port}/api/v1")`;
    } else {
      const endpointModel =
        selectedModel.toLowerCase() === 'chatterbox'
          ? 'ResembleAI/chatterbox'
          : selectedModel.toLowerCase();
      return `client = InferenceClient(
    api_key="YOUR_HF_TOKEN",  # Get your token from https://huggingface.co/settings/tokens
    model="${endpointModel}",
)`;
    }
  }

  function generateImportCode() {
    const clientCode = generateClientInitCode();

    if (mode === 'local') {
      return `from huggingface_hub import InferenceClient

${clientCode}`;
    } else {
      return `from huggingface_hub import InferenceClient

${clientCode}`;
    }
  }

  function copyToClipboard(text, message = 'Copied to clipboard!') {
    navigator.clipboard.writeText(text).then(() => {
      copyNotification = message;
      setTimeout(() => {
        copyNotification = null;
      }, 2000);
    });
  }

  function copyAllCode() {
    const parts = [];

    if (setupCode) {
      const isTerminalCommand =
        setupCode.includes('pip install') || setupCode.includes('hfstudio start');
      const language = isTerminalCommand ? 'bash' : '';
      parts.push(`## Setup (Run in Terminal)\n\n\`\`\`${language}\n${setupCode}\n\`\`\``);
    }

    if (importCode) {
      parts.push(`## Imports (Python)\n\n\`\`\`python\n${importCode}\n\`\`\``);
    }

    codeHistory.forEach((entry, i) => {
      parts.push(`## Cell ${i + 1}\n\n\`\`\`python\n${entry.code}\n\`\`\``);
    });

    const markdownContent = parts.join('\n\n');
    copyToClipboard(markdownContent, 'All code copied as Markdown!');
  }

  function toggleHistoryAudio(entry) {
    if (!entry.audioElement) {
      entry.audioElement = new Audio(entry.result.url);
      entry.audioElement.addEventListener('ended', () => {
        entry.isPlaying = false;
        codeHistory = [...codeHistory];
      });
    }

    if (entry.isPlaying) {
      entry.audioElement.pause();
      entry.isPlaying = false;
    } else {
      codeHistory.forEach((e) => {
        if (e !== entry && e.isPlaying && e.audioElement) {
          e.audioElement.pause();
          e.isPlaying = false;
        }
      });
      entry.audioElement.play();
      entry.isPlaying = true;
    }
    codeHistory = [...codeHistory];
  }

  function downloadHistoryAudio(url, title) {
    const link = document.createElement('a');
    link.href = url;
    link.download = `${title || 'audio'}.wav`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }

  function formatDuration(seconds) {
    if (!seconds) return '0:00';
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    return `${mins}:${secs.toString().padStart(2, '0')}`;
  }

  $: if (mode) {
    setupCode = generateSetupCode();
    importCode = generateImportCode();
  }

  onMount(async () => {
    await loadHistoryFromDatabase();
  });
</script>

<svelte:head>
  <title>Code Recorder - HFStudio</title>
</svelte:head>

<div class="flex-1 bg-gray-50 overflow-y-auto">
  <Navbar {historyCount} />

  <div class="max-w-4xl mx-auto p-8">
    <!-- Header -->
    <div class="mb-6">
      <div>
        <h2 class="text-2xl font-semibold text-gray-900">Code Recorder</h2>
        <p class="text-sm text-gray-600 mt-1">
          {#if mode === 'local'}
            Python code to reproduce your actions using a local HFStudio server
          {:else}
            Python code to reproduce your actions via the API
          {/if}
        </p>
      </div>

      <!-- Toggle and Copy All button row -->
      <div class="flex items-center justify-between mt-4">
        <!-- API/Local Mode Toggle -->
        <div class="flex items-center bg-gray-100 rounded-md p-0.5">
          <button
            class="px-3 py-1 text-sm font-medium rounded transition-colors {mode === 'api'
              ? 'bg-white shadow-sm'
              : 'text-gray-600'}"
            on:click={() => (mode = 'api')}
          >
            API
          </button>
          <button
            class="px-3 py-1 text-sm font-medium rounded transition-colors {mode === 'local'
              ? 'bg-white shadow-sm'
              : 'text-gray-600'}"
            on:click={() => (mode = 'local')}
          >
            Local
          </button>
        </div>

        {#if codeHistory.length > 0 || setupCode || importCode}
          <div class="flex items-center gap-2">
            <button
              on:click={resetHistory}
              class="flex items-center bg-red-50 hover:bg-red-100 rounded-md px-3 py-1.5 transition-colors"
              title="Clear history"
            >
              <RotateCcw size={16} class="text-red-600" />
              <span class="ml-2 text-sm font-medium text-red-600">Reset history</span>
            </button>
            <button
              on:click={copyAllCode}
              class="flex items-center bg-gray-100 hover:bg-gray-200 rounded-md px-3 py-1.5 transition-colors"
            >
              <Copy size={16} class="text-gray-600" />
              <span class="ml-2 text-sm font-medium text-gray-600">Copy all as Markdown</span>
            </button>
          </div>
        {/if}
      </div>
    </div>

    <!-- Code sections -->
    <div class="space-y-6">
      <!-- Setup Section - Always shown -->
      {#if setupCode}
        <div class="bg-white rounded-lg border border-gray-200 overflow-hidden">
          <div
            class="flex items-center justify-between px-4 py-2 bg-amber-50 border-b border-amber-200"
          >
            <div class="flex items-center gap-2">
              <span class="text-sm font-medium text-amber-900">Setup (Run in Terminal)</span>
              <span class="text-xs bg-amber-100 text-amber-700 px-2 py-0.5 rounded">Run once</span>
            </div>
            <button
              on:click={() => copyToClipboard(setupCode)}
              class="p-1.5 hover:bg-amber-100 rounded transition-colors"
              title="Copy setup code"
            >
              <Copy size={14} class="text-amber-600" />
            </button>
          </div>
          <div class="relative">
            {#if setupCode === 'pip install huggingface-hub'}
              <pre class="p-4 overflow-x-auto bg-gray-50"><code
                  class="language-bash text-sm text-black">{setupCode}</code
                ></pre>
            {:else}
              <pre class="p-4 overflow-x-auto bg-gray-50"><code class="language-bash text-sm"
                  >{@html Prism.highlight(setupCode, Prism.languages.bash, 'bash')}</code
                ></pre>
            {/if}
          </div>
        </div>
      {/if}

      <!-- Import Section -->
      {#if importCode}
        <div class="bg-white rounded-lg border border-gray-200 overflow-hidden">
          <div
            class="flex items-center justify-between px-4 py-2 bg-blue-50 border-b border-blue-200"
          >
            <div class="flex items-center gap-2">
              <span class="text-sm font-medium text-blue-900">Imports (Python)</span>
              <span class="text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded">Run once</span>
            </div>
            <button
              on:click={() => copyToClipboard(importCode)}
              class="p-1.5 hover:bg-blue-100 rounded transition-colors"
              title="Copy import code"
            >
              <Copy size={14} class="text-blue-600" />
            </button>
          </div>
          <div class="relative">
            <pre class="p-4 overflow-x-auto bg-gray-50"><code class="language-python text-sm"
                >{@html Prism.highlight(importCode, Prism.languages.python, 'python')}</code
              ></pre>
          </div>
        </div>
      {/if}

      <!-- Show "start using UI" message when no import code or history -->
      {#if !importCode && codeHistory.length === 0}
        <div class="bg-white rounded-lg border border-gray-200 p-8 text-center">
          <p class="text-gray-500">Start using the UI to see generated code here</p>
        </div>
      {/if}

      <!-- History entries -->
      {#each codeHistory as entry, i (entry.id)}
        <div class="bg-white rounded-lg border border-gray-200 overflow-hidden shadow-sm">
          <!-- Code cell -->
          <div class="border-b border-gray-200">
            <div
              class="flex items-center justify-between px-4 py-2 bg-gray-50 border-b border-gray-100"
            >
              <span class="text-sm font-medium text-gray-700">Cell {i + 1}</span>
              <button
                on:click={() => copyToClipboard(entry.code)}
                class="p-1.5 hover:bg-gray-200 rounded transition-colors"
                title="Copy code"
              >
                <Copy size={14} class="text-gray-600" />
              </button>
            </div>
            <div class="relative">
              <pre class="p-4 overflow-x-auto bg-gray-50"><code class="language-python text-sm"
                  >{@html Prism.highlight(entry.code, Prism.languages.python, 'python')}</code
                ></pre>
            </div>
          </div>

          <!-- Result (audio player) -->
          {#if entry.result && entry.result.type === 'audio'}
            <div class="bg-gradient-to-b from-gray-50 to-white p-4">
              <div class="bg-white rounded-lg border border-gray-200 p-4 shadow-sm">
                <div class="flex items-center justify-between">
                  <div class="flex items-center gap-3 flex-1">
                    <button
                      on:click={() => toggleHistoryAudio(entry)}
                      class="w-10 h-10 bg-gradient-to-r from-amber-500 to-orange-500 rounded-full flex items-center justify-center text-white hover:from-amber-600 hover:to-orange-600 transition-colors shadow-md"
                    >
                      {#if entry.isPlaying}
                        <Pause size={18} />
                      {:else}
                        <Play size={18} class="ml-0.5" />
                      {/if}
                    </button>
                    <div class="flex-1">
                      <div class="text-sm font-medium text-gray-900 truncate">
                        {entry.result.title || 'Generated Audio'}
                      </div>
                      <div class="text-xs text-gray-500">
                        Duration: {formatDuration(entry.result.duration || 0)}
                      </div>
                    </div>
                  </div>
                  <div class="flex items-center gap-1">
                    <button
                      on:click={() => downloadHistoryAudio(entry.result.url, entry.result.title)}
                      class="p-2 hover:bg-gray-100 rounded-lg transition-colors"
                      title="Download"
                    >
                      <Download size={16} class="text-gray-600" />
                    </button>
                    <button
                      class="p-2 hover:bg-gray-100 rounded-lg transition-colors"
                      title="Share"
                    >
                      <Share size={16} class="text-gray-600" />
                    </button>
                  </div>
                </div>
                <audio
                  bind:this={entry.audioElement}
                  src={entry.result.url}
                  on:ended={() => (entry.isPlaying = false)}
                  class="hidden"
                />
              </div>
            </div>
          {/if}
        </div>
      {/each}
    </div>
  </div>
</div>

<!-- Copy notification toast -->
{#if copyNotification}
  <div
    class="fixed bottom-4 right-4 px-4 py-2 bg-gray-900 text-white rounded-lg shadow-lg z-50 animate-fade-in"
  >
    {copyNotification}
  </div>
{/if}

<style>
  @keyframes fade-in {
    from {
      opacity: 0;
      transform: translateY(10px);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }

  .animate-fade-in {
    animation: fade-in 0.3s ease-out;
  }
</style>
