<script lang="ts">
  import { Check, GitCommitHorizontal, LoaderCircle, RotateCcw, Settings, ShieldCheck, Sparkles } from "@lucide/svelte";
  import type { CommitAiPhase, CommitAiProvider } from "../types";

  interface Props {
    commitMessage: string;
    canCommit: boolean;
    commitBlockReason: string;
    hasRepository: boolean;
    isBusy: boolean;
    operation: string;
    stagedCount: number;
    commitAiProvider: CommitAiProvider;
    commitAiPhase: CommitAiPhase;
    commitAiGenerating: boolean;
    commitAiReviewing: boolean;
    commitAiSplitting: boolean;
    canAmend: boolean;
    amendMode: boolean;
    onCommit: () => void;
    onCommitMessageChange: (msg: string) => void;
    onGenerateCommitMessage: () => void;
    onReviewStaged: () => void;
    onSplitStaged: () => void;
    onOpenAiSettings: () => void;
    onToggleAmend: (checked: boolean) => void;
    onUndoLastCommit: () => void;
  }

  let {
    commitMessage = "",
    canCommit = false,
    commitBlockReason = "",
    hasRepository = false,
    isBusy = false,
    operation = "",
    stagedCount = 0,
    commitAiProvider = "local",
    commitAiPhase = "idle",
    commitAiGenerating = false,
    commitAiReviewing = false,
    commitAiSplitting = false,
    canAmend = false,
    amendMode = false,
    onCommit = () => {},
    onCommitMessageChange = () => {},
    onGenerateCommitMessage = () => {},
    onReviewStaged = () => {},
    onSplitStaged = () => {},
    onOpenAiSettings = () => {},
    onToggleAmend = () => {},
    onUndoLastCommit = () => {},
  }: Props = $props();

  function handleSubmit(event: SubmitEvent) {
    event.preventDefault();
    onCommit();
  }

  function aiButtonTitle(provider: CommitAiProvider, phase: CommitAiPhase, staged: number): string {
    if (staged === 0) return "Stage changes first";
    if (provider === "local" && phase === "loading") return "AI model is downloading/loading — this happens once";
    if (provider === "local" && phase === "error") return "AI model failed to load — check AI settings";
    return "Generate commit message with AI from the staged diff";
  }

  let localModelLoading = $derived(commitAiProvider === "local" && commitAiPhase === "loading");
  let canGenerate = $derived(
    hasRepository &&
    !isBusy &&
    !commitAiGenerating &&
    !commitAiReviewing &&
    stagedCount > 0 &&
    (commitAiProvider !== "local" || commitAiPhase === "ready"),
  );
  let canReview = $derived(canGenerate && commitAiProvider !== "local");
  let canSplit = $derived(canReview && stagedCount > 1 && !commitAiSplitting);
</script>

<section class="panel commit-panel" aria-label="Commit">
  <div class="section-head">
    <div>
      <span class="eyebrow">Create revision</span>
      <h2 class="mt-0.5 text-ink text-base font-bold leading-tight">Commit</h2>
    </div>
    <div class="commit-head-actions">
      <span class="pill pill-count">{stagedCount} staged</span>
      <button
        class="commit-review-button"
        type="button"
        onclick={onSplitStaged}
        disabled={!canSplit}
        title={commitAiProvider === "local" ? "Commit splitting currently requires an API provider" : "Suggest logical commits for the staged files"}
      >
        {#if commitAiSplitting}<LoaderCircle class="spin" size={14} aria-hidden="true" />{:else}<GitCommitHorizontal size={14} aria-hidden="true" />{/if}
        Split
      </button>
      <button
        class="commit-review-button"
        type="button"
        onclick={onReviewStaged}
        disabled={!canReview}
        title={commitAiProvider === "local" ? "Pre-commit review currently requires an API provider" : stagedCount === 0 ? "Stage changes first" : "Review staged changes for bugs and risks"}
      >
        {#if commitAiReviewing}<LoaderCircle class="spin" size={14} aria-hidden="true" />{:else}<ShieldCheck size={14} aria-hidden="true" />{/if}
        Review
      </button>
      <button
        class="commit-generate-button"
        type="button"
        onclick={onGenerateCommitMessage}
        disabled={!canGenerate}
        title={aiButtonTitle(commitAiProvider, commitAiPhase, stagedCount)}
      >
        {#if commitAiGenerating || localModelLoading}<LoaderCircle class="spin" size={14} aria-hidden="true" />{:else}<Sparkles size={14} aria-hidden="true" />{/if}
        Generate
      </button>
      <button class="commit-settings-button" type="button" onclick={onOpenAiSettings} disabled={isBusy} title="AI settings" aria-label="AI settings">
        <Settings size={14} aria-hidden="true" />
      </button>
    </div>
  </div>

  <form class="commit-form" onsubmit={handleSubmit}>
    <textarea
      value={commitMessage}
      oninput={(e) => onCommitMessageChange((e.target as HTMLTextAreaElement).value)}
      placeholder="Commit message"
      disabled={!hasRepository || isBusy}
    ></textarea>
    {#if commitBlockReason}
      <p class="commit-block-reason">{commitBlockReason}</p>
    {/if}
    {#if canAmend}
      <div class="commit-amend-row">
        <label class="commit-amend-toggle">
          <input
            type="checkbox"
            checked={amendMode}
            disabled={isBusy}
            onchange={(e) => onToggleAmend((e.target as HTMLInputElement).checked)}
          />
          Amend last commit
        </label>
        <button
          class="btn-secondary commit-undo-button"
          type="button"
          onclick={onUndoLastCommit}
          disabled={isBusy}
          title="Undo the last commit — its changes come back as uncommitted changes (not pushed yet, so safe)"
        >
          <RotateCcw size={13} aria-hidden="true" />
          Undo last commit
        </button>
      </div>
    {/if}
    <div class="commit-actions-row flex-shrink-0">
      <button class="btn-primary flex-1" type="submit" disabled={!canCommit} title={commitBlockReason || (amendMode ? "Amend the last commit" : "Commit staged changes")}>
        {#if operation === "Committing" || operation === "Amending"}
          <LoaderCircle class="spin" size={16} aria-hidden="true" />
        {:else}
          <Check size={16} aria-hidden="true" />
        {/if}
        {amendMode ? "Amend" : "Commit"}
      </button>
    </div>
  </form>
</section>
