"use client";

import { diffWords, diffArrays } from "diff";
import { useTranslations } from "next-intl";

export type DiffSnapshot = {
  title: string;
  description?: string | null;
  ingredients: Array<{ rawName: string; quantity?: string | number | null; unit?: string | null; note?: string | null }>;
  steps: Array<{ instruction: string; timerSeconds?: number | null }>;
};

function ingredientLine(i: DiffSnapshot["ingredients"][number]): string {
  return [i.quantity, i.unit, i.rawName, i.note && `(${i.note})`].filter(Boolean).join(" ");
}

function stepLine(s: DiffSnapshot["steps"][number]): string {
  return s.instruction;
}

function TextDiff({ before, after }: { before: string; after: string }) {
  const parts = diffWords(before, after);
  return (
    <p className="text-sm leading-relaxed">
      {parts.map((part, i) => (
        <span
          key={i}
          className={
            part.added
              ? "bg-green-500/20 text-green-700 dark:text-green-400"
              : part.removed
                ? "bg-red-500/20 text-red-700 dark:text-red-400 line-through"
                : undefined
          }
        >
          {part.value}
        </span>
      ))}
    </p>
  );
}

function ListDiff({ before, after }: { before: string[]; after: string[] }) {
  const changes = diffArrays(before, after);
  const rows: React.ReactNode[] = [];
  let key = 0;

  for (let i = 0; i < changes.length; i++) {
    const change = changes[i]!;

    // A removed chunk immediately followed by an added chunk is usually an
    // edit, not a delete+insert — word-diff matching pairs so a one-word
    // tweak doesn't render as an unreadable full remove + full add.
    if (change.removed && changes[i + 1]?.added) {
      const removedItems = change.value;
      const addedItems = changes[i + 1]!.value;
      const pairCount = Math.min(removedItems.length, addedItems.length);

      for (let j = 0; j < pairCount; j++) {
        rows.push(
          <div key={key++} className="rounded px-2 py-1">
            <TextDiff before={removedItems[j]!} after={addedItems[j]!} />
          </div>
        );
      }
      for (let j = pairCount; j < removedItems.length; j++) {
        rows.push(
          <div key={key++} className="bg-red-500/10 rounded px-2 py-1 text-sm text-red-700 dark:text-red-400 line-through">
            − {removedItems[j]}
          </div>
        );
      }
      for (let j = pairCount; j < addedItems.length; j++) {
        rows.push(
          <div key={key++} className="bg-green-500/10 rounded px-2 py-1 text-sm text-green-700 dark:text-green-400">
            + {addedItems[j]}
          </div>
        );
      }
      i++; // consumed the paired "added" chunk too
      continue;
    }

    for (const item of change.value) {
      if (change.added) {
        rows.push(
          <div key={key++} className="bg-green-500/10 rounded px-2 py-1 text-sm text-green-700 dark:text-green-400">
            + {item}
          </div>
        );
      } else if (change.removed) {
        rows.push(
          <div key={key++} className="bg-red-500/10 rounded px-2 py-1 text-sm text-red-700 dark:text-red-400 line-through">
            − {item}
          </div>
        );
      } else {
        rows.push(
          <div key={key++} className="px-2 py-1 text-sm text-muted-foreground">
            {item}
          </div>
        );
      }
    }
  }

  return <div className="space-y-1">{rows}</div>;
}

export function VersionDiffView({ before, after }: { before: DiffSnapshot; after: DiffSnapshot }) {
  const t = useTranslations("recipe");
  return (
    <div className="space-y-6">
      <section className="space-y-2">
        <h3 className="text-sm font-semibold text-muted-foreground">{t("diffTitleLabel")}</h3>
        <TextDiff before={before.title} after={after.title} />
      </section>

      {(before.description || after.description) && (
        <section className="space-y-2">
          <h3 className="text-sm font-semibold text-muted-foreground">{t("diffDescriptionLabel")}</h3>
          <TextDiff before={before.description ?? ""} after={after.description ?? ""} />
        </section>
      )}

      <section className="space-y-2">
        <h3 className="text-sm font-semibold text-muted-foreground">{t("diffIngredientsLabel")}</h3>
        <ListDiff before={before.ingredients.map(ingredientLine)} after={after.ingredients.map(ingredientLine)} />
      </section>

      <section className="space-y-2">
        <h3 className="text-sm font-semibold text-muted-foreground">{t("diffStepsLabel")}</h3>
        <ListDiff before={before.steps.map(stepLine)} after={after.steps.map(stepLine)} />
      </section>
    </div>
  );
}
