<script lang="ts">
  import { ChevronLeft, ChevronRight, GitCompare, History, RotateCcw } from "@lucide/svelte";
  import iconUrl from "../../../src-tauri/icons/icon.png";
  import type { GitCommit } from "../types";

  interface Props {
    fileHistory: GitCommit[];
    selectedExplorerPath: string;
    selectedExplorerLabel: string;
    hasRepository: boolean;
    isBusy: boolean;
    isLoading?: boolean;
    onDiff: (commit: GitCommit) => void;
    onRestore: (commit: GitCommit) => void;
    collapsed?: boolean;
    onToggleCollapsed?: () => void;
  }

  let {
    fileHistory = [],
    selectedExplorerPath = "",
    selectedExplorerLabel = "File history",
    hasRepository = false,
    isBusy = false,
    isLoading = false,
    onDiff = () => {},
    onRestore = () => {},
    collapsed = false,
    onToggleCollapsed = () => {},
  }: Props = $props();

  function formatCommitDate(value: string): string {
    const date = new Date(value);
    if (Number.isNaN(date.getTime())) return value;
    return new Intl.DateTimeFormat(undefined, { dateStyle: "medium", timeStyle: "short" }).format(date);
  }

  function fileName(path: string): string {
    return path.split("/").pop() ?? path;
  }

  function pathTooltip(node: HTMLElement, text: string) {
    let el: HTMLDivElement | null = null;

    function show(e: MouseEvent) {
      if (!text || !text.includes("/")) return;
      el = document.createElement("div");
      el.className = "path-tooltip";
      el.textContent = text;
      document.body.appendChild(el);
      move(e);
    }

    function move(e: MouseEvent) {
      if (!el) return;
      const tw = el.offsetWidth;
      const left = Math.max(8, Math.min(e.clientX - tw / 2, window.innerWidth - tw - 8));
      el.style.left = `${left}px`;
      el.style.top  = `${e.clientY - 44}px`;
    }

    function hide() {
      el?.remove();
      el = null;
    }

    node.addEventListener("mouseenter", show);
    node.addEventListener("mousemove", move);
    node.addEventListener("mouseleave", hide);

    return {
      update(v: string) { text = v; },
      destroy() {
        hide();
        node.removeEventListener("mouseenter", show);
        node.removeEventListener("mousemove", move);
        node.removeEventListener("mouseleave", hide);
      },
    };
  }
</script>

<section class="panel file-history-panel grid grid-rows-[auto_1fr] overflow-hidden" class:collapsed aria-label="Selected file history">
  {#if collapsed}
    <button
      class="file-history-rail-toggle"
      type="button"
      onclick={onToggleCollapsed}
      aria-expanded={!collapsed}
      title="Expand file history"
      aria-label="Expand file history panel"
    >
      <ChevronLeft size={16} aria-hidden="true" />
      <span>File history</span>
      {#if selectedExplorerPath}
        <small>{fileHistory.length}</small>
      {/if}
    </button>
  {:else}
  <div class="section-head file-history-head">
    <div class="file-history-heading">
      <span class="eyebrow">{selectedExplorerLabel}</span>
      <h2
        class="file-history-name"
        use:pathTooltip={selectedExplorerPath}
      >{selectedExplorerPath ? fileName(selectedExplorerPath) : "No file"}</h2>
    </div>
    <div class="file-history-head-actions">
      <span class="pill pill-count file-history-count">{fileHistory.length}</span>
      <button
        class="file-history-toggle panel-collapse-toggle"
        type="button"
        onclick={onToggleCollapsed}
        aria-expanded={!collapsed}
        title="Collapse file history"
        aria-label="Collapse file history panel"
      >
        <ChevronRight size={14} aria-hidden="true" />
      </button>
    </div>
  </div>

  {#if !hasRepository}
    <div class="blank-state">No repository loaded.</div>
  {:else if !selectedExplorerPath}
    <div class="blank-state">Select a file in Explorer.</div>
  {:else if isLoading}
    <div class="file-history-loading" role="status" aria-live="polite">
      <div class="file-history-loading-mark" aria-hidden="true">
        <span class="file-history-loading-halo"></span>
        <svg class="file-history-loading-traces" viewBox="0 0 120 120">
          <path class="fhl-trace fhl-trace-main" d="M14 82 C38 60, 48 58, 60 60 S84 66, 106 36" />
          <path class="fhl-trace fhl-trace-branch" d="M28 36 C52 48, 70 70, 91 94" />
        </svg>
        <img src={iconUrl} alt="" class="file-history-loading-icon" />
      </div>
      <span class="file-history-loading-label">Loading history…</span>
      <span class="file-history-loading-bar" aria-hidden="true"><span></span></span>
    </div>
  {:else if fileHistory.length === 0}
    <div class="blank-state">No history returned for this selection.</div>
  {:else}
    <div class="history-list overflow-auto p-2">
      {#each fileHistory as item (item.hash)}
        <article class="commit-row compact file-history-row">
          <div class="commit-line">
            <History size={16} aria-hidden="true" />
            <div class="commit-line-text">
              <strong title={item.summary}>{item.summary}</strong>
              <span>{item.short_hash} - {item.author_name}</span>
            </div>
          </div>

          <div class="commit-actions file-history-actions">
            <time datetime={item.date}>{formatCommitDate(item.date)}</time>
            <div class="commit-action-buttons">
              <button class="btn-sm" type="button" onclick={() => onDiff(item)} disabled={isBusy} title="Show changes vs working tree">
                <GitCompare size={15} aria-hidden="true" />
                Diff
              </button>
              <button class="btn-sm" type="button" onclick={() => onRestore(item)} disabled={isBusy} title="Restore selected file from this commit">
                <RotateCcw size={15} aria-hidden="true" />
                Restore
              </button>
            </div>
          </div>
        </article>
      {/each}
    </div>
  {/if}
  {/if}
</section>
