<script lang="ts">
  // @ts-nocheck
  import { onMount, onDestroy } from "svelte";
  import { invoke } from "@tauri-apps/api/core";
  import { listen } from "@tauri-apps/api/event";
  import { settings, addToHistory } from "$lib/stores/page.svelte.js";
  import { profilesStore } from "$lib/stores/profiles.svelte.ts";
  import Card from "$lib/components/Card.svelte";
  import EmptyState from "$lib/components/EmptyState.svelte";
  import { exportTranscript } from "$lib/utils/export.js";
  import { hasTauriRuntime } from "$lib/utils/runtime";
  import { toasts } from "$lib/stores/toasts.svelte.js";
  import { Upload } from 'lucide-svelte';

  let fileTranscript = $state("");
  let segments = $state([]);
  let isDragOver = $state(false);
  let progress = $state(0);
  let progressText = $state("");
  let fileName = $state("");
  let error = $state("");
  let transcribing = $state(false);
  let showExportMenu = $state(false);

  let unlistenDrop = null;
  let unlistenEnter = null;
  let unlistenLeave = null;

  onMount(async () => {
    unlistenDrop = await listen("tauri://drag-drop", async (event) => {
      isDragOver = false;
      if (event.payload?.paths?.length > 0) {
        await transcribeFiles(event.payload.paths);
      }
    });
    unlistenEnter = await listen("tauri://drag-enter", () => { isDragOver = true; });
    unlistenLeave = await listen("tauri://drag-leave", () => { isDragOver = false; });
  });

  onDestroy(() => {
    if (unlistenDrop) unlistenDrop();
    if (unlistenEnter) unlistenEnter();
    if (unlistenLeave) unlistenLeave();
  });

  async function handleBrowse() {
    try {
      const { open } = await import("@tauri-apps/plugin-dialog");
      const paths = await open({
        multiple: true,
        filters: [{
          name: "Audio/Video",
          extensions: ["mp3", "wav", "m4a", "mp4", "flac", "ogg", "webm", "mov", "mkv"],
        }],
      });
      if (paths) {
        const pathList = Array.isArray(paths) ? paths : [paths];
        await transcribeFiles(pathList);
      }
    } catch (err) {
      error = typeof err === "string" ? err : err.message || "Failed to open file dialog";
    }
  }

  async function transcribeFiles(paths) {
    transcribing = true;
    error = "";
    fileTranscript = "";
    segments = [];

    for (let i = 0; i < paths.length; i++) {
      const path = paths[i];
      fileName = path.split(/[\\/]/).pop() || path;
      progress = (i / paths.length) * 100;
      progressText = `Transcribing ${i + 1}/${paths.length}...`;

      try {
        const result = await invoke("transcribe_file", {
          path,
          engine: settings.engine,
          language: settings.language,
          initialPrompt: "",
          profileId: profilesStore.activeProfileId,
          removeFillers: settings.removeFillers,
          britishEnglish: settings.britishEnglish,
          antiHallucination: settings.antiHallucination,
          formatMode: settings.formatMode,
        });

        const text = result.segments.map((s) => s.text).join(" ").trim();

        if (paths.length > 1) {
          fileTranscript += `--- ${fileName} ---\n${text}\n\n`;
        } else {
          fileTranscript = text;
        }

        segments = [...segments, ...result.segments];

        addToHistory({
          id: crypto.randomUUID(),
          date: new Date().toLocaleString("en-GB"),
          source: fileName,
          profileId: profilesStore.activeProfileId,
          preview: text.slice(0, 120),
          text,
          segments: result.segments,
          duration: result.duration,
          language: result.language,
          engine: result.engine ?? settings.engine,
          modelId: result.modelId ?? null,
        });
      } catch (err) {
        error = `Failed: ${fileName}. ${typeof err === "string" ? err : err.message}`;
      }
    }

    progress = 100;
    progressText = "Done";
    transcribing = false;

    setTimeout(() => {
      progress = 0;
      progressText = "";
      fileName = "";
    }, 3000);
  }

  function copyAll() {
    if (fileTranscript) {
      navigator.clipboard.writeText(fileTranscript).catch(() => {
        invoke("copy_to_clipboard", { text: fileTranscript }).catch(() => {});
      });
    }
  }

  async function handleExport(format) {
    if (!fileTranscript) return;
    showExportMenu = false;
    const content = exportTranscript(fileTranscript, segments, format);
    const extMap = { txt: "txt", vtt: "vtt", srt: "srt", md: "md", csv: "csv", html: "html" };
    const ext = extMap[format] || "txt";
    const defaultPath = `magnotia-file-${new Date().toISOString().slice(0, 10)}.${ext}`;

    if (hasTauriRuntime()) {
      try {
        const { save } = await import("@tauri-apps/plugin-dialog");
        const path = await save({
          title: `Export ${format.toUpperCase()} transcript`,
          defaultPath,
          filters: [{ name: format.toUpperCase(), extensions: [ext] }],
        });
        if (!path) return;
        await invoke("write_text_file_cmd", { path, contents: content });
        toasts.success(`Exported ${format.toUpperCase()} transcript`);
        return;
      } catch (err) {
        console.error("file transcript export failed", err);
        error = `Export failed: ${typeof err === "string" ? err : err.message || err}`;
        return;
      }
    }

    const blob = new Blob([content], { type: "text/plain" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = defaultPath;
    a.click();
    URL.revokeObjectURL(url);
  }
</script>

<div class="flex flex-col h-full overflow-y-auto animate-fade-in">
  <!-- Title -->
  <h2 class="font-display text-[26px] italic text-text px-7 pt-6 pb-4">File Transcription</h2>

  <!-- Drop zone. The dashed border IS the affordance, so we drop the
       outer Card (which doubled the surface treatment per brand spec)
       and let the dashed div be the single surface. The region landmark
       carries an explicit accessible name per WCAG ARIA13. -->
  <div class="px-7 pb-3">
    <div
      class="flex flex-col items-center justify-center py-10 px-6 rounded-xl border-2 border-dashed
        {isDragOver
          ? 'border-accent bg-accent-subtle scale-[1.01]'
          : 'border-border hover:border-text-tertiary'}"
      style="transition-duration: var(--duration-ui)"
      role="region"
      aria-label="Audio file drop zone"
    >
      {#if !fileTranscript && !transcribing}
        <EmptyState
          icon={Upload}
          message="Drop an audio file or click to browse"
        />
      {:else}
        <div class="w-10 h-10 rounded-full bg-bg-elevated flex items-center justify-center mb-3">
          <Upload size={20} class="text-text-tertiary" aria-hidden="true" />
        </div>
        <p class="text-[13px] text-text-secondary text-center">
          Drop audio or video files here
        </p>
      {/if}
      <p class="text-[12px] text-text-secondary text-center mt-1.5">
        MP3, WAV, M4A, MP4, FLAC, OGG
      </p>
    </div>
  </div>

  <!-- Browse buttons + progress -->
  <div class="flex items-center gap-2 px-7 pb-3">
    <button
      class="btn-lg rounded-lg font-medium text-white bg-accent hover:bg-accent-hover
             shadow-[var(--shadow-accent-raised)]"
      onclick={handleBrowse}
      disabled={transcribing}
    >
      Browse Files
    </button>
    <div class="flex-1"></div>
    {#if progressText}
      <span class="text-[12px] text-text-secondary animate-fade-in">{progressText}</span>
    {/if}
  </div>

  <!-- Error -->
  {#if error}
    <div class="px-7 pb-2 animate-fade-in">
      <div class="px-4 py-2 rounded-lg bg-danger/10 border border-danger/20 text-[12px] text-danger">
        {error}
      </div>
    </div>
  {/if}

  <!-- Progress bar -->
  {#if progress > 0}
    <div class="px-7 pb-3 animate-fade-in">
      <div class="h-[3px] bg-bg-elevated rounded-full overflow-hidden">
        <div
          class="h-full bg-accent rounded-full shadow-[var(--shadow-accent-glow)]"
          style="width: {progress}%; transition-duration: var(--duration-ui)"
        ></div>
      </div>
      {#if fileName}
        <p class="text-[12px] text-text-secondary mt-1.5">{fileName}</p>
      {/if}
    </div>
  {/if}

  <!-- File transcript -->
  <div class="flex-1 px-7 pb-3 min-h-0">
    <Card classes="h-full flex flex-col">
      <textarea
        class="font-transcript flex-1 w-full bg-transparent text-text p-6
               resize-none placeholder:text-text-tertiary"
        placeholder="Transcribed text will appear here..."
        bind:value={fileTranscript}
        data-no-transition
        aria-label="File transcript"
        aria-live="polite"
      ></textarea>
    </Card>
  </div>

  <!-- Bottom actions -->
  <div class="flex gap-0.5 px-7 pb-4">
    <button class="btn-md rounded-lg text-text-secondary hover:bg-hover hover:text-text" onclick={copyAll}>Copy</button>
    <div class="relative">
      <button
        class="btn-md rounded-lg text-text-secondary hover:bg-hover hover:text-text"
        onclick={() => showExportMenu = !showExportMenu}
      >Export</button>
      {#if showExportMenu}
        <div class="absolute left-0 bottom-full mb-1 bg-bg-card border border-border rounded-lg shadow-lg py-1 z-10 animate-fade-in min-w-[120px]">
          {#each [["txt", "Plain Text"], ["md", "Markdown"], ["csv", "CSV"], ["html", "HTML"], ["srt", "SRT Subtitles"], ["vtt", "WebVTT"]] as [fmt, label]}
            <button
              class="w-full text-left btn-md text-text-secondary hover:bg-hover hover:text-text"
              onclick={() => handleExport(fmt)}
            >{label}</button>
          {/each}
        </div>
      {/if}
    </div>
  </div>
</div>
