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

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

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

  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);

  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="Select branches or commits to compare" tabindex="-1">
    <header class="dialog-header">
      <div>
        <span class="eyebrow">Compare</span>
        <h2 class="mt-0.5 text-ink text-base font-bold leading-tight">Compare branches or commits</h2>
      </div>
      <button class="dialog-close" type="button" onclick={onClose} title="Close">
        <X size={18} aria-hidden="true" />
      </button>
    </header>

    {#if targetCount < 2}
      <div class="blank-state">At least two branches or commits are needed to compare.</div>
    {:else}
      <form class="compare-form" onsubmit={handleSubmit}>
        <label class="compare-field">
          <span>Base</span>
          <select
            value={compareFrom}
            onchange={(e) => onCompareFromChange((e.target as HTMLSelectElement).value)}
            disabled={isBusy}
          >
            <option value="" disabled>Select a branch or commit</option>
            {#if localBranches.length > 0}
              <optgroup label="Local branches">
                {#each localBranches as branch (branch.name)}
                  <option value={branchValue(branch)}>{branch.name}{branch.current ? " (current)" : ""}</option>
                {/each}
              </optgroup>
            {/if}
            {#if remoteBranches.length > 0}
              <optgroup label="Remote branches">
                {#each remoteBranches as branch (branch.name)}
                  <option value={branchValue(branch)}>{branch.name}</option>
                {/each}
              </optgroup>
            {/if}
            {#if commits.length > 0}
              <optgroup label="Recent commits">
                {#each commits as item (item.hash)}
                  <option value={item.hash}>{commitOptionLabel(item)}</option>
                {/each}
              </optgroup>
            {/if}
          </select>
        </label>

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

        <label class="compare-field">
          <span>Compare with</span>
          <select
            value={compareTo}
            onchange={(e) => onCompareToChange((e.target as HTMLSelectElement).value)}
            disabled={isBusy}
          >
            <option value="" disabled>Select a branch or commit</option>
            {#if localBranches.length > 0}
              <optgroup label="Local branches">
                {#each localBranches as branch (branch.name)}
                  <option value={branchValue(branch)}>{branch.name}{branch.current ? " (current)" : ""}</option>
                {/each}
              </optgroup>
            {/if}
            {#if remoteBranches.length > 0}
              <optgroup label="Remote branches">
                {#each remoteBranches as branch (branch.name)}
                  <option value={branchValue(branch)}>{branch.name}</option>
                {/each}
              </optgroup>
            {/if}
            {#if commits.length > 0}
              <optgroup label="Recent commits">
                {#each commits as item (item.hash)}
                  <option value={item.hash}>{commitOptionLabel(item)}</option>
                {/each}
              </optgroup>
            {/if}
          </select>
        </label>

        <button class="btn-primary" type="submit" disabled={!canCompare}>
          {#if operation === "Comparing revisions"}
            <LoaderCircle class="spin" size={16} aria-hidden="true" />
          {:else}
            <GitCompare size={16} aria-hidden="true" />
          {/if}
          Compare
        </button>
      </form>

      {#if compareFrom && compareTo && compareFrom === compareTo}
        <div class="blank-state">Select two different branches or commits to compare.</div>
      {:else}
        <div class="compare-target-help">
          The two branch tips are compared across the entire repository. Uncommitted working-tree changes are not included.
        </div>
      {/if}
    {/if}
  </div>
</div>
