<script lang="ts">
  import { onDestroy } from "svelte";
  import { open as openDialog } from "@tauri-apps/plugin-dialog";
  import { Download, FolderOpen, LoaderCircle, X } from "@lucide/svelte";

  interface Props {
    isBusy: boolean;
    error: string;
    onClone: (remoteUrl: string, parentPath: string, directoryName: string) => void;
    onClose: () => void;
  }

  let {
    isBusy = false,
    error = "",
    onClone = () => {},
    onClose = () => {},
  }: Props = $props();

  let remoteUrl = $state("");
  let parentPath = $state("");
  let directoryName = $state("");
  let directoryNameEdited = $state(false);
  let directoryAutoName = $state("");
  let browseError = $state("");
  let visibleError = $state("");
  let errorHideTimer: ReturnType<typeof setTimeout> | undefined;

  let directorySuggestion = $derived(directoryNameFromRemoteUrl(remoteUrl));
  let canSubmit = $derived(
    !isBusy &&
    remoteUrl.trim().length > 0 &&
    parentPath.trim().length > 0,
  );

  $effect(() => {
    const nextError = error || browseError;
    if (errorHideTimer) clearTimeout(errorHideTimer);
    visibleError = nextError;
    if (nextError) {
      errorHideTimer = setTimeout(() => {
        visibleError = "";
      }, 6000);
    }
  });

  onDestroy(() => {
    if (errorHideTimer) clearTimeout(errorHideTimer);
  });

  function directoryNameFromRemoteUrl(url: string): string {
    const trimmed = url.trim().split(/[?#]/, 1)[0]?.replace(/[\\/]+$/g, "") ?? "";
    const lastSegment = trimmed.split(/[\\/:]/).filter(Boolean).pop() ?? "";
    return lastSegment.replace(/\.git$/i, "").trim();
  }

  function errorToMessage(error: unknown): string {
    if (error instanceof Error) return error.message;
    if (typeof error === "string") return error;
    try { return JSON.stringify(error) ?? "Unknown error"; } catch { return "Unknown error"; }
  }

  async function chooseParentFolder() {
    if (isBusy) return;
    browseError = "";
    try {
      const selected = await openDialog({
        title: "Select clone destination",
        directory: true,
        multiple: false,
        defaultPath: parentPath.trim() || undefined,
      });
      if (typeof selected !== "string") return;
      parentPath = selected;
    } catch (error) {
      browseError = errorToMessage(error);
    }
  }

  function handleRemoteInput(event: Event) {
    const nextRemoteUrl = (event.currentTarget as HTMLInputElement).value;
    if (directoryNameEdited) return;
    directoryAutoName = directoryNameFromRemoteUrl(nextRemoteUrl);
    directoryName = directoryAutoName;
  }

  function handleDirectoryInput(event: Event) {
    const nextDirectoryName = (event.currentTarget as HTMLInputElement).value;
    directoryNameEdited = nextDirectoryName.trim().length > 0 && nextDirectoryName !== directoryAutoName;
  }

  function submit(event: SubmitEvent) {
    event.preventDefault();
    if (!canSubmit) return;
    onClone(remoteUrl.trim(), parentPath.trim(), directoryName.trim());
  }

</script>

<div class="dialog-backdrop" role="presentation">
  <div class="dialog clone-repository-dialog" role="dialog" aria-modal="true" aria-label="Clone repository" tabindex="-1">
    <header class="dialog-header">
      <div>
        <span class="eyebrow">Repository Management</span>
        <h2 class="mt-0.5 text-ink text-base font-bold leading-tight">Clone repository</h2>
      </div>
      <button class="dialog-close" type="button" onclick={onClose} disabled={isBusy} title="Close">
        <X size={18} aria-hidden="true" />
      </button>
    </header>

    <form class="clone-dialog-form" onsubmit={submit}>
      <label class="clone-dialog-field">
        <span>Remote URL</span>
        <!-- svelte-ignore a11y_autofocus -->
        <input
          bind:value={remoteUrl}
          oninput={handleRemoteInput}
          autocomplete="off"
          spellcheck="false"
          placeholder="https://github.com/org/project.git"
          disabled={isBusy}
          autofocus
        />
      </label>

      <label class="clone-dialog-field">
        <span>Destination</span>
        <div class="clone-dialog-path-field">
          <input
            bind:value={parentPath}
            autocomplete="off"
            spellcheck="false"
            placeholder="Choose parent folder"
            disabled={isBusy}
          />
          <button class="btn-secondary" type="button" onclick={chooseParentFolder} disabled={isBusy}>
            <FolderOpen size={14} aria-hidden="true" />
            Browse
          </button>
        </div>
      </label>

      <label class="clone-dialog-field">
        <span>Folder name</span>
        <input
          bind:value={directoryName}
          oninput={handleDirectoryInput}
          autocomplete="off"
          spellcheck="false"
          placeholder={directorySuggestion || "Optional"}
          disabled={isBusy}
        />
      </label>

      {#if visibleError}
        <div class="clone-dialog-error" role="alert">{visibleError}</div>
      {/if}

      <div class="clone-dialog-actions">
        <button class="btn-secondary" type="button" onclick={onClose} disabled={isBusy}>
          Cancel
        </button>
        <button class="btn-primary" type="submit" disabled={!canSubmit}>
          {#if isBusy}
            <LoaderCircle class="spin" size={16} aria-hidden="true" />
          {:else}
            <Download size={16} aria-hidden="true" />
          {/if}
          Clone
        </button>
      </div>
    </form>
  </div>
</div>
