// SnapshotEditor — groups the active accounts by balance category and
// renders one `SnapshotLineRow` per account.
//
// Each row dispatches its variant on the account's OWN `account.kind` (#213)
// inside `SnapshotLineRow` (simple → scalar value; detailed → holdings basket).
// The editor itself only carries the values/holdings down and the change
// handlers up.

import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import type {
  BalanceAccountWithCategory,
  BalanceCategory,
  BalanceSecurity,
} from "../../shared/types";
import type { HoldingDraft } from "../../hooks/useSnapshotEditor";
import type { HoldingColumnMapping } from "../../utils/csvAutoDetect";
import type { SecurityPick } from "./SecurityPicker";
import SnapshotLineRow from "./SnapshotLineRow";
import { renderCategoryLabelFromCategory } from "../../utils/renderCategoryLabel";

interface Props {
  accounts: BalanceAccountWithCategory[];
  categories: BalanceCategory[];
  /** account_id → string-typed value (simple accounts). */
  values: Record<number, string>;
  /** account_id → holdings basket (detailed accounts, #213). */
  holdings: Record<number, HoldingDraft[]>;
  /** Securities catalogue for the SecurityPicker autocomplete (#214). */
  securities: BalanceSecurity[];
  onValueChange: (accountId: number, next: string) => void;
  onAddHolding: (accountId: number, assetType?: "stock" | "crypto") => void;
  onRemoveHolding: (accountId: number, rowId: string) => void;
  onHoldingFieldChange: (
    accountId: number,
    rowId: string,
    field: keyof Omit<HoldingDraft, "rowId">,
    value: string
  ) => void;
  /** Apply a SecurityPicker selection to a holding row (#214). */
  onHoldingSecurityPick: (
    accountId: number,
    rowId: string,
    pick: SecurityPick
  ) => void;
  /** Import a batch of holdings from a CSV into a detailed account (#245). */
  onImportHoldings: (
    accountId: number,
    rows: string[][],
    mapping: HoldingColumnMapping
  ) => void;
  disabled?: boolean;
  /** Snapshot date (YYYY-MM-DD) — forwarded to PriceFetchControl (Issue #158). */
  snapshotDate?: string;
}

export default function SnapshotEditor({
  accounts,
  categories,
  values,
  holdings,
  securities,
  onValueChange,
  onAddHolding,
  onRemoveHolding,
  onHoldingFieldChange,
  onHoldingSecurityPick,
  onImportHoldings,
  disabled,
  snapshotDate,
}: Props) {
  const { t } = useTranslation();

  // Group accounts by their category, preserving the categories' sort_order
  // first then the account name within each group.
  const groups = useMemo(() => {
    const byCategory = new Map<number, BalanceAccountWithCategory[]>();
    for (const acc of accounts) {
      const list = byCategory.get(acc.balance_category_id) ?? [];
      list.push(acc);
      byCategory.set(acc.balance_category_id, list);
    }
    const sortedCategories = [...categories].sort(
      (a, b) => a.sort_order - b.sort_order || a.key.localeCompare(b.key)
    );
    return sortedCategories
      .map((cat) => ({
        category: cat,
        accounts: (byCategory.get(cat.id) ?? []).sort((a, b) =>
          a.name.localeCompare(b.name)
        ),
      }))
      .filter((group) => group.accounts.length > 0);
  }, [accounts, categories]);

  if (accounts.length === 0) {
    return (
      <div className="bg-[var(--card)] rounded-xl border border-[var(--border)] p-8 text-center text-[var(--muted-foreground)]">
        {t("balance.snapshot.editor.empty")}
      </div>
    );
  }

  return (
    <div className="flex flex-col gap-4">
      {groups.map(({ category, accounts: catAccounts }) => (
        <div
          key={category.id}
          className="bg-[var(--card)] rounded-xl border border-[var(--border)] overflow-hidden"
        >
          <div className="px-4 py-2 bg-[var(--muted)] border-b border-[var(--border)]">
            <h3 className="text-sm font-semibold">
              {renderCategoryLabelFromCategory(category, t)}
            </h3>
          </div>
          <div className="px-4">
            {catAccounts.map((acc) => (
              <SnapshotLineRow
                key={acc.id}
                account={acc}
                value={values[acc.id] ?? ""}
                holdings={holdings[acc.id]}
                securities={securities}
                onChange={(next) => onValueChange(acc.id, next)}
                onAddHolding={() =>
                  onAddHolding(acc.id, acc.category_asset_type ?? "stock")
                }
                onRemoveHolding={(rowId) => onRemoveHolding(acc.id, rowId)}
                onHoldingFieldChange={(rowId, field, value) =>
                  onHoldingFieldChange(acc.id, rowId, field, value)
                }
                onHoldingSecurityPick={(rowId, pick) =>
                  onHoldingSecurityPick(acc.id, rowId, pick)
                }
                onImportHoldings={(rows, mapping) =>
                  onImportHoldings(acc.id, rows, mapping)
                }
                disabled={disabled}
                snapshotDate={snapshotDate}
              />
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}
