import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { X } from "lucide-react";
import { getDb } from "../../services/db";
import type { MappingRow } from "../../services/categoryMappingService";

interface TransactionRow {
  id: number;
  date: string;
  description: string;
  amount: number;
}

interface TransactionPreviewPanelProps {
  row: MappingRow | null;
  onClose: () => void;
}

const MAX_TRANSACTIONS = 50;

/**
 * Side panel that shows transactions currently attached to a v2 category
 * selected in the simulate table. Read-only — exists purely to give the user
 * enough context to decide whether the proposed v1 target is correct.
 *
 * We fetch lazily (once per selected row id) and cap at 50 rows. If the user
 * has more than 50 tx attached, a small "... and N more" line is rendered.
 */
export default function TransactionPreviewPanel({
  row,
  onClose,
}: TransactionPreviewPanelProps) {
  const { t, i18n } = useTranslation();
  const [loading, setLoading] = useState(false);
  const [transactions, setTransactions] = useState<TransactionRow[]>([]);
  const [totalCount, setTotalCount] = useState(0);

  useEffect(() => {
    let cancelled = false;
    if (row === null) {
      setTransactions([]);
      setTotalCount(0);
      return;
    }
    const load = async () => {
      setLoading(true);
      try {
        const db = await getDb();
        const txs = await db.select<TransactionRow[]>(
          `SELECT id, date, description, amount
           FROM transactions
           WHERE category_id = $1
           ORDER BY date DESC, id DESC
           LIMIT $2`,
          [row.v2CategoryId, MAX_TRANSACTIONS],
        );
        const count = await db.select<Array<{ cnt: number }>>(
          `SELECT COUNT(*) AS cnt FROM transactions WHERE category_id = $1`,
          [row.v2CategoryId],
        );
        if (!cancelled) {
          setTransactions(txs);
          setTotalCount(count[0]?.cnt ?? 0);
        }
      } catch {
        if (!cancelled) {
          setTransactions([]);
          setTotalCount(0);
        }
      } finally {
        if (!cancelled) setLoading(false);
      }
    };
    load();
    return () => {
      cancelled = true;
    };
  }, [row]);

  if (row === null) return null;

  const locale = i18n.language?.startsWith("en") ? "en-CA" : "fr-CA";
  const formatAmount = (value: number): string =>
    new Intl.NumberFormat(locale, {
      style: "currency",
      currency: "CAD",
      minimumFractionDigits: 2,
    }).format(value);
  const formatDate = (iso: string): string => {
    try {
      return new Date(iso).toLocaleDateString(locale);
    } catch {
      return iso;
    }
  };

  const overflow = Math.max(0, totalCount - transactions.length);

  return (
    <aside
      className="fixed inset-y-0 right-0 w-full max-w-md bg-[var(--card)] border-l border-[var(--border)] shadow-xl z-40 flex flex-col"
      aria-label={t("categoriesSeed.migration.simulate.panel.title")}
    >
      <header className="flex items-center justify-between px-4 py-3 border-b border-[var(--border)]">
        <div className="min-w-0">
          <h3 className="font-semibold truncate text-[var(--foreground)]">
            {row.v2CategoryName}
          </h3>
          <p className="text-xs text-[var(--muted-foreground)]">
            {t("categoriesSeed.migration.simulate.panel.subtitle", {
              count: totalCount,
            })}
          </p>
        </div>
        <button
          type="button"
          onClick={onClose}
          aria-label={t("categoriesSeed.migration.simulate.panel.close")}
          className="rounded-md p-1.5 text-[var(--muted-foreground)] hover:bg-[var(--muted)] hover:text-[var(--foreground)]"
        >
          <X size={18} />
        </button>
      </header>

      <div className="flex-1 overflow-y-auto p-2">
        {loading ? (
          <p className="p-4 text-sm text-[var(--muted-foreground)]">
            {t("common.loading")}
          </p>
        ) : transactions.length === 0 ? (
          <p className="p-4 text-sm text-[var(--muted-foreground)]">
            {t("categoriesSeed.migration.simulate.panel.noTransactions")}
          </p>
        ) : (
          <ul className="space-y-1">
            {transactions.map((tx) => (
              <li
                key={tx.id}
                className="flex items-center justify-between gap-3 px-2 py-1.5 rounded-md hover:bg-[var(--muted)] text-sm"
              >
                <div className="min-w-0">
                  <p className="truncate text-[var(--foreground)]">
                    {tx.description}
                  </p>
                  <p className="text-xs text-[var(--muted-foreground)]">
                    {formatDate(tx.date)}
                  </p>
                </div>
                <span
                  className={
                    tx.amount < 0
                      ? "shrink-0 font-mono text-red-600 dark:text-red-400"
                      : "shrink-0 font-mono text-green-600 dark:text-green-400"
                  }
                >
                  {formatAmount(tx.amount)}
                </span>
              </li>
            ))}
            {overflow > 0 && (
              <li className="px-2 py-2 text-xs text-[var(--muted-foreground)] text-center">
                {t("categoriesSeed.migration.simulate.panel.overflow", {
                  count: overflow,
                })}
              </li>
            )}
          </ul>
        )}
      </div>

      <footer className="px-4 py-3 border-t border-[var(--border)] text-xs text-[var(--muted-foreground)]">
        {row.v1TargetName
          ? t("categoriesSeed.migration.simulate.panel.willMapTo", {
              target: row.v1TargetName,
            })
          : t("categoriesSeed.migration.simulate.panel.noTarget")}
      </footer>
    </aside>
  );
}
