// BalanceOverviewCard — top summary tile of /balance.
//
// Issue #141 (Bilan #3). Displays:
//   - The latest aggregate snapshot total (sum across all accounts on the
//     most recent snapshot date).
//   - Δ% versus the previous chronological snapshot (null when only one
//     snapshot exists; rendered as "—").
//   - A staleness warning when the latest snapshot is older than 60 days.
//   - "+ Nouveau snapshot" CTA → `/balance/snapshot`.

import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Plus, TrendingUp, TrendingDown, AlertTriangle } from "lucide-react";
import { Link } from "react-router-dom";
import type {
  LatentGainRollup,
  SnapshotTotalPoint,
} from "../../services/balance.service";

const STALENESS_DAYS = 60;
const cadFormatter = (value: number) =>
  new Intl.NumberFormat("en-CA", {
    style: "currency",
    currency: "CAD",
    maximumFractionDigits: 2,
  }).format(value);

interface BalanceOverviewCardProps {
  /** The full evolution series for the active period (latest at the end). */
  totals: SnapshotTotalPoint[];
  /**
   * Aggregated latent gain across all detailed accounts (Issue #216). Shown as
   * a total figure alongside the net worth. Absent / no detailed account ⇒ the
   * latent-gain line is hidden (no zero-noise for users without securities).
   */
  latentGainRollup?: LatentGainRollup;
}

export default function BalanceOverviewCard({
  totals,
  latentGainRollup,
}: BalanceOverviewCardProps) {
  const { t, i18n } = useTranslation();

  const summary = useMemo(() => {
    if (totals.length === 0) {
      return null;
    }
    const last = totals[totals.length - 1];
    const prev = totals.length >= 2 ? totals[totals.length - 2] : null;
    const deltaPct =
      prev && prev.total !== 0
        ? ((last.total - prev.total) / Math.abs(prev.total)) * 100
        : null;
    const ageMs = Date.now() - new Date(last.snapshot_date).getTime();
    const ageDays = Math.floor(ageMs / (1000 * 60 * 60 * 24));
    return {
      latest: last,
      deltaPct,
      isStale: ageDays > STALENESS_DAYS,
      ageDays,
    };
  }, [totals]);

  const dateLocale = i18n.language === "fr" ? "fr-CA" : "en-CA";
  const formatDate = (iso: string) =>
    new Date(iso).toLocaleDateString(dateLocale, {
      year: "numeric",
      month: "long",
      day: "numeric",
    });

  // Total latent gain across detailed accounts. Only render when at least one
  // detailed account contributed a bucket — otherwise the line is hidden.
  const latent = useMemo(() => {
    if (
      !latentGainRollup ||
      (latentGainRollup.byClass.length === 0 &&
        latentGainRollup.byVehicle.length === 0)
    ) {
      return null;
    }
    return latentGainRollup.grandTotal;
  }, [latentGainRollup]);

  return (
    <div className="bg-[var(--card)] rounded-xl border border-[var(--border)] p-6">
      <div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4">
        <div>
          <p className="text-sm text-[var(--muted-foreground)]">
            {t("balance.overview.latestTotal")}
          </p>
          {summary ? (
            <>
              <p className="text-3xl font-bold mt-1">
                {cadFormatter(summary.latest.total)}
              </p>
              <p className="text-xs text-[var(--muted-foreground)] mt-1">
                {t("balance.overview.asOf", {
                  date: formatDate(summary.latest.snapshot_date),
                })}
              </p>
              {latent && (
                <p className="text-sm mt-2 inline-flex items-center gap-1.5">
                  <span className="text-[var(--muted-foreground)]">
                    {t("balance.latentGain.totalLabel")}
                  </span>
                  <span
                    className={`font-medium ${
                      latent.total_gain >= 0
                        ? "text-[var(--positive)]"
                        : "text-[var(--negative)]"
                    }`}
                  >
                    {latent.total_gain >= 0 ? "+" : ""}
                    {cadFormatter(latent.total_gain)}
                    {latent.total_gain_pct !== null && (
                      <span className="text-[var(--muted-foreground)] font-normal text-xs ml-1">
                        ({latent.total_gain >= 0 ? "+" : ""}
                        {(latent.total_gain_pct * 100).toFixed(2)}%)
                      </span>
                    )}
                  </span>
                  {latent.has_unknown_book_cost && (
                    <AlertTriangle
                      size={12}
                      className="text-amber-500"
                      aria-label={t("balance.latentGain.partial")}
                    />
                  )}
                </p>
              )}
            </>
          ) : (
            <p className="text-sm text-[var(--muted-foreground)] mt-2">
              {t("balance.overview.noSnapshots")}
            </p>
          )}
        </div>

        <div className="flex flex-col items-stretch sm:items-end gap-2">
          {summary && summary.deltaPct !== null && (
            <div
              className={`inline-flex items-center gap-1 text-sm font-medium ${
                summary.deltaPct >= 0
                  ? "text-[var(--positive)]"
                  : "text-[var(--negative)]"
              }`}
            >
              {summary.deltaPct >= 0 ? (
                <TrendingUp size={16} />
              ) : (
                <TrendingDown size={16} />
              )}
              {summary.deltaPct >= 0 ? "+" : ""}
              {summary.deltaPct.toFixed(2)}%
              <span className="text-[var(--muted-foreground)] font-normal text-xs ml-1">
                {t("balance.overview.vsPrevious")}
              </span>
            </div>
          )}

          <Link
            to="/balance/snapshot"
            className="inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-[var(--primary)] text-white text-sm font-medium hover:opacity-90"
          >
            <Plus size={16} />
            {t("balance.overview.newSnapshot")}
          </Link>
        </div>
      </div>

      {summary?.isStale && (
        <div className="mt-4 flex items-start gap-2 p-3 rounded-lg bg-amber-500/10 text-amber-700 dark:text-amber-400 border border-amber-500/30 text-sm">
          <AlertTriangle size={16} className="mt-0.5 shrink-0" />
          <span>
            {t("balance.overview.staleWarning", { days: summary.ageDays })}
          </span>
        </div>
      )}
    </div>
  );
}
