<script lang="ts">
  import { ArrowRight, GitCompare, Info, LoaderCircle, X } from "@lucide/svelte";
  import type { GitBranch, GitCommit } from "../types";
  import SelectMenu from "./SelectMenu.svelte";

  interface Props {
    commits: GitCommit[];
    branches: GitBranch[];
    compareFrom: string;
    compareTo: string;
    canCompare: boolean;
    isBusy: boolean;
    operation: string;
    language?: "en" | "de";
    onCompareFromChange: (val: string) => void;
    onCompareToChange: (val: string) => void;
    onCompare: () => void;
    onClose: () => void;
  }

  let {
    commits = [],
    branches = [],
    compareFrom = "",
    compareTo = "",
    canCompare = false,
    isBusy = false,
    operation = "",
    language = "en",
    onCompareFromChange = () => {},
    onCompareToChange = () => {},
    onCompare = () => {},
    onClose = () => {},
  }: Props = $props();

  let isGerman = $derived(language === "de");

  function commitOptionLabel(item: GitCommit): string {
    return `${item.short_hash} - ${item.summary}`;
  }

  function branchValue(branch: GitBranch): string {
    return branch.remote ? `refs/remotes/${branch.name}` : `refs/heads/${branch.name}`;
  }

  let localBranches = $derived(branches.filter((branch) => !branch.remote));
  let remoteBranches = $derived(branches.filter((branch) => branch.remote));
  let targetCount = $derived(branches.length + commits.length);
  let compareOptions = $derived([
    ...localBranches.map((branch) => ({
      value: branchValue(branch),
      label: `${branch.name}${branch.current ? (isGerman ? " (aktuell)" : " (current)") : ""}`,
      group: isGerman ? "Lokale Branches" : "Local branches",
    })),
    ...remoteBranches.map((branch) => ({
      value: branchValue(branch),
      label: branch.name,
      group: isGerman ? "Remote-Branches" : "Remote branches",
    })),
    ...commits.map((item) => ({
      value: item.hash,
      label: commitOptionLabel(item),
      group: "Commits",
    })),
  ]);

  function handleSubmit(event: SubmitEvent) {
    event.preventDefault();
    onCompare();
  }
</script>

<div
  class="dialog-backdrop"
  role="presentation"
>
  <div class="dialog compare-select-dialog" role="dialog" aria-modal="true" aria-label={isGerman ? "Branches oder Commits vergleichen" : "Compare branches or commits"} tabindex="-1">
    <header class="compare-dialog-head">
      <div class="compare-dialog-title">
        <span class="compare-dialog-mark"><GitCompare size={18} aria-hidden="true" /></span>
        <div>
          <h2>{isGerman ? "Branches oder Commits vergleichen" : "Compare branches or commits"}</h2>
          <p>{isGerman ? "Zwei Repository-Stände direkt gegenüberstellen" : "Review two repository states side by side"}</p>
        </div>
      </div>
      <button class="dialog-close" type="button" onclick={onClose} title={isGerman ? "Schließen" : "Close"} aria-label={isGerman ? "Vergleich schließen" : "Close comparison"}>
        <X size={18} aria-hidden="true" />
      </button>
    </header>

    <form class="compare-select-shell" onsubmit={handleSubmit}>
      <div class="compare-select-body">
        {#if targetCount < 2}
          <div class="blank-state">{isGerman ? "Für einen Vergleich werden mindestens zwei Branches oder Commits benötigt." : "At least two branches or commits are needed to compare."}</div>
        {:else}
          <section class="compare-target-panel">
            <div class="compare-target-heading">
              <h3>{isGerman ? "Vergleichsbereich" : "Comparison range"}</h3>
              <p>{isGerman ? "Wähle Ausgangspunkt und Ziel des Vergleichs." : "Choose the starting point and target for the comparison."}</p>
            </div>
            <div class="compare-form">
              <label class="compare-field">
                <span>{isGerman ? "Ausgangsbasis" : "Base"}</span>
                <SelectMenu class="compare-target-select" value={compareFrom} options={compareOptions} placeholder={isGerman ? "Branch oder Commit wählen" : "Select a branch or commit"} showSelectedGroup disabled={isBusy} onChange={onCompareFromChange} />
              </label>

              <span class="compare-arrow-shell"><ArrowRight size={18} aria-hidden="true" /></span>

              <label class="compare-field">
                <span>{isGerman ? "Vergleichen mit" : "Compare with"}</span>
                <SelectMenu class="compare-target-select" value={compareTo} options={compareOptions} placeholder={isGerman ? "Branch oder Commit wählen" : "Select a branch or commit"} showSelectedGroup disabled={isBusy} onChange={onCompareToChange} />
              </label>
            </div>
          </section>

          {#if compareFrom && compareTo && compareFrom === compareTo}
            <div class="compare-target-help compare-target-warning"><Info size={15} aria-hidden="true" /><span>{isGerman ? "Wähle zwei unterschiedliche Branches oder Commits." : "Select two different branches or commits to compare."}</span></div>
          {:else}
            <div class="compare-target-help"><Info size={15} aria-hidden="true" /><span>{isGerman ? "Verglichen werden die vollständigen Repository-Stände. Nicht committete Änderungen im Arbeitsverzeichnis sind nicht enthalten." : "The complete repository states are compared. Uncommitted working-tree changes are not included."}</span></div>
          {/if}
        {/if}
      </div>
      <footer class="compare-select-footer">
        <span>{isGerman ? `${targetCount} Ziele verfügbar` : `${targetCount} targets available`}</span>
        <div>
          <button class="btn-secondary" type="button" onclick={onClose}>{isGerman ? "Abbrechen" : "Cancel"}</button>
          <button class="btn-primary" type="submit" disabled={!canCompare || targetCount < 2}>
            {#if operation === "Comparing revisions"}
              <LoaderCircle class="spin" size={16} aria-hidden="true" />
            {:else}
              <GitCompare size={16} aria-hidden="true" />
            {/if}
            {isGerman ? "Vergleich öffnen" : "Open comparison"}
          </button>
        </div>
      </footer>
    </form>
  </div>
</div>
