"use client";

import React, { useState } from "react";
import { useI18n } from "@/lib/i18n/context";
import { ProcessedReceipt, ValidationIssue } from "@/lib/schema/receipt";
import { confirmReceiptReviewed } from "@/lib/ai/recalculate";
import { formatMoney, receiptCurrency } from "./receiptFormat";
import { AlertTriangle, Check, ChevronLeft, ChevronRight, Edit3 } from "lucide-react";

interface MicroPromptBarProps {
  receiptsNeedingReview: ProcessedReceipt[];
  /**
   * Legacy-Rückruf: erhält nur die Beleg-ID. Der Aufrufer muss den Beleg dann
   * selbst über `confirmReceiptReviewed` bestätigen.
   */
  onConfirmReview: (receiptId: string) => void;
  /**
   * Bevorzugter Rückruf: erhält den bereits über {@link confirmReceiptReviewed}
   * bestätigten Beleg und muss ihn nur noch speichern. Optional, damit
   * bestehende Aufrufer mit `onConfirmReview` unverändert weiterlaufen.
   */
  onConfirmReceipt?: (updated: ProcessedReceipt) => void;
  onEditReceipt: (receipt: ProcessedReceipt) => void;
}

/** Errors zuerst, Reihenfolge innerhalb einer Stufe bleibt stabil. */
function sortIssues(issues: ValidationIssue[]): ValidationIssue[] {
  return [
    ...issues.filter((issue) => issue.severity === "error"),
    ...issues.filter((issue) => issue.severity !== "error"),
  ];
}

/**
 * Leitet die anzuzeigenden Befunde ab.
 *
 * Bevorzugt das neue `validation.issues`-Array. Altdatensätze aus IndexedDB
 * kennen das Feld nicht – dort wird der Legacy-`reviewReason` zu einem
 * Einzelbefund umgeformt, damit die Liste nie leer bleibt.
 */
function issuesOf(receipt: ProcessedReceipt, isDe: boolean = false): ValidationIssue[] {
  const issues = receipt.validation?.issues;
  if (Array.isArray(issues)) {
    // Altdatensätze können `null`-Einträge oder Befunde ohne Text enthalten.
    const usable = issues.filter(
      (issue): issue is ValidationIssue =>
        !!issue && typeof issue.message === "string" && issue.message.length > 0
    );
    if (usable.length > 0) return sortIssues(usable);
  }

  const legacyReason = receipt.validation?.reviewReason;
  if (legacyReason) {
    return [
      {
        field: (receipt.validation?.reviewField ?? "none") as ValidationIssue["field"],
        severity: receipt.validation?.isMathValid === false ? "error" : "warning",
        message: legacyReason,
      },
    ];
  }

  return [
    {
      field: "none",
      severity: "warning",
      message: isDe
        ? `Bitte Betrag (${formatMoney(
            receipt.totalAmount?.value ?? 0,
            receiptCurrency(receipt)
          )}) und Datum (${receipt.date?.isoDate ?? "—"}) gegen den Beleg prüfen.`
        : `Please verify amount (${formatMoney(
            receipt.totalAmount?.value ?? 0,
            receiptCurrency(receipt)
          )}) and date (${receipt.date?.isoDate ?? "—"}) against receipt image.`,
    },
  ];
}

export function MicroPromptBar({
  receiptsNeedingReview,
  onConfirmReview,
  onConfirmReceipt,
  onEditReceipt,
}: MicroPromptBarProps) {
  const { t, language } = useI18n();
  const isDe = language === "de";
  const [cursor, setCursor] = useState(0);

  if (receiptsNeedingReview.length === 0) return null;

  const total = receiptsNeedingReview.length;
  const index = Math.min(cursor, total - 1);
  const current = receiptsNeedingReview[index];
  const issues = issuesOf(current, isDe);
  const errorCount = issues.filter((issue) => issue.severity === "error").length;

  /**
   * "Als geprüft markieren" heißt: der Benutzer übernimmt den Beleg so, wie er
   * ist. `confirmReceiptReviewed` setzt `userConfirmed` und räumt die
   * Warteschlange, verfälscht `isMathValid` aber ausdrücklich nicht.
   */
  const handleConfirm = () => {
    if (onConfirmReceipt) {
      onConfirmReceipt(confirmReceiptReviewed(current));
      return;
    }
    onConfirmReview(current.id);
  };

  return (
    <div
      data-testid="micro-prompt-bar"
      className="mb-6 border border-[#F59E0B] bg-[#FEF3C7] p-4 font-sans animate-fade-in"
    >
      <div className="flex flex-col justify-between gap-4 sm:flex-row sm:items-start">
        {/* Befunde */}
        <div className="flex items-start gap-3">
          <div className="flex h-8 w-8 shrink-0 items-center justify-center bg-[#000000] text-white">
            <AlertTriangle className="h-4 w-4 text-[#F59E0B]" />
          </div>
          <div className="min-w-0">
            <div className="flex flex-wrap items-center gap-2">
              <span className="bg-[#FDE68A] px-2 py-0.5 font-mono text-[10px] font-bold uppercase tracking-caps text-[#92400E]">
                {isDe ? "Prüfung erforderlich" : "Review Required"}
              </span>
              <span
                data-testid="review-queue-counter"
                className="font-mono text-[10px] font-semibold text-[#78350F]"
              >
                {isDe ? `Beleg ${index + 1} von ${total} offen` : `Receipt ${index + 1} of ${total} pending`}
              </span>
              <span className="font-mono text-[10px] text-[#78350F]">
                {isDe
                  ? `${errorCount} Fehler · ${issues.length - errorCount} Hinweise`
                  : `${errorCount} errors · ${issues.length - errorCount} warnings`}
              </span>
            </div>

            <p className="mt-1 text-xs font-bold text-black sm:text-sm">
              {current.merchant?.name} ·{" "}
              {formatMoney(current.totalAmount?.value ?? 0, receiptCurrency(current))} ·{" "}
              {current.date?.isoDate ?? "—"}
            </p>

            {/* Alle Befunde auf einmal – nicht nur der erste. */}
            <ul data-testid="review-issue-list" className="mt-1.5 space-y-1">
              {issues.map((issue, issueIndex) => (
                <li key={issueIndex} className="flex items-start gap-2 text-[11px]">
                  <span
                    className={`mt-0.5 shrink-0 px-1.5 font-mono text-[9px] uppercase ${
                      issue.severity === "error"
                        ? "bg-[#FFDAD6] text-[#93000A]"
                        : "bg-[#FDE68A] text-[#92400E]"
                    }`}
                  >
                    {issue.severity === "error" ? (isDe ? "Fehler" : "Error") : (isDe ? "Hinweis" : "Warning")}
                  </span>
                  <span className="text-black">{issue.message}</span>
                </li>
              ))}
            </ul>
          </div>
        </div>

        {/* Aktionen */}
        <div className="flex shrink-0 flex-col items-end gap-2 self-end font-mono text-xs uppercase tracking-caps sm:self-start">
          <div className="flex items-center gap-2">
            <button
              onClick={() => onEditReceipt(current)}
              className="flex items-center gap-1.5 border border-[#000000] bg-white px-3.5 py-1.5 text-black transition-colors hover:bg-[#F8FAFC]"
            >
              <Edit3 className="h-3.5 w-3.5 text-black" />
              <span>{isDe ? (t.dashboard?.reviewPromptEdit || "Korrigieren") : "Inspect / Edit"}</span>
            </button>

            <button
              onClick={handleConfirm}
              data-testid="confirm-review-button"
              title={
                isDe
                  ? "Markiert den Beleg als von dir geprüft und akzeptiert. Die Rechenprüfung wird dadurch nicht verändert – abweichende Beträge bleiben dokumentiert."
                  : "Marks the receipt as reviewed and accepted as-is. Math verification remains documented."
              }
              className="flex items-center gap-1.5 bg-[#000000] px-3.5 py-1.5 font-medium text-white transition-colors hover:bg-[#334155]"
            >
              <Check className="h-3.5 w-3.5 text-emerald-400" />
              <span>{isDe ? "Als geprüft markieren" : "Mark as Reviewed"}</span>
            </button>
          </div>

          {total > 1 && (
            <div className="flex items-center gap-1">
              <button
                onClick={() => setCursor(Math.max(0, index - 1))}
                disabled={index === 0}
                aria-label={isDe ? "Vorheriger Beleg" : "Previous receipt"}
                className="border border-[#F59E0B] bg-white p-1 text-[#92400E] disabled:opacity-30"
              >
                <ChevronLeft className="h-3.5 w-3.5" />
              </button>
              <button
                onClick={() => setCursor(Math.min(total - 1, index + 1))}
                disabled={index >= total - 1}
                aria-label={isDe ? "Nächster Beleg" : "Next receipt"}
                className="border border-[#F59E0B] bg-white p-1 text-[#92400E] disabled:opacity-30"
              >
                <ChevronRight className="h-3.5 w-3.5" />
              </button>
            </div>
          )}

          <span className="max-w-[280px] text-right normal-case tracking-normal text-[10px] text-[#78350F]">
            {isDe
              ? "\"Als geprüft\" heißt: du akzeptierst den Beleg so. Die Zahlen werden dadurch nicht korrigiert – abweichende Beträge bleiben vermerkt."
              : "\"Reviewed\" means: you accept the receipt as-is. Numerical discrepancies remain documented in the audit ledger."}
          </span>
        </div>
      </div>
    </div>
  );
}
