// FilterPanel — shared filter bar for the report pages (Issue #274, epic #260).
//
// Design: a "slot" component. Each report page owns its own temporal state
// (Compare = a local reducer, Trends/ByCategory = the `sources` query string
// via useReportsPeriod, Budget = a plain year) and renders its own control
// (PeriodSelector / CompareReferenceMonthPicker / YearNavigator / …), passed
// in as-is via `temporalControl`. FilterPanel does NOT own a `temporalMode`
// enum and does not know which control it is rendering — an earlier design
// unifying temporal state behind such an enum was rejected specifically to
// avoid mixing state sources (see spec-plan-rapports-uniformes-suite.md).
// The only state this component actually owns/shares across report pages is
// the account (import source) filter.
//
// `accounts`/`accountIds` refer to `ImportSource` rows (bank statement import
// sources, e.g. "Compte chèque Desjardins") — a disjoint id space from the
// Bilan module's `balance_accounts` ("Compte" in that module's own UI). The
// copy in this component deliberately says "sources" everywhere, never
// "comptes"/"accounts", so the two concepts never read as the same filter.

import type { ReactNode } from "react";
import { useTranslation } from "react-i18next";
import { Inbox } from "lucide-react";
import type { ImportSource } from "../../shared/types";

export interface FilterPanelProps {
  /** The page's own temporal control, rendered as-is. */
  temporalControl: ReactNode;
  /** Selected import source ids. Empty array = no filter (all sources). */
  accountIds: number[];
  onAccountIdsChange: (accountIds: number[]) => void;
  /** Import sources available to filter on. */
  accounts: ImportSource[];
}

/**
 * Toggles `id` in/out of `accountIds` (add if absent, remove if present),
 * preserving the relative order of the remaining ids. Pure and exported so
 * the selection logic is unit-testable without rendering the component.
 */
export function toggleAccountId(accountIds: number[], id: number): number[] {
  return accountIds.includes(id)
    ? accountIds.filter((existing) => existing !== id)
    : [...accountIds, id];
}

export default function FilterPanel({
  temporalControl,
  accountIds,
  onAccountIdsChange,
  accounts,
}: FilterPanelProps) {
  const { t } = useTranslation();

  const accountsLabel = t("reports.filters.accounts.label");

  return (
    <div className="bg-[var(--card)] rounded-xl p-4 border border-[var(--border)] mb-4 flex flex-wrap items-start gap-4">
      <div>{temporalControl}</div>

      <div className="flex flex-col gap-1.5">
        <span className="inline-flex items-center gap-1.5 text-xs font-medium text-[var(--muted-foreground)]">
          <Inbox size={14} />
          {accountsLabel}
        </span>
        <div
          className="flex flex-wrap gap-x-4 gap-y-1.5"
          role="group"
          aria-label={accountsLabel}
        >
          {accounts.map((account) => (
            <label
              key={account.id}
              className="flex items-center gap-1.5 text-sm cursor-pointer"
            >
              <input
                type="checkbox"
                checked={accountIds.includes(account.id)}
                onChange={() =>
                  onAccountIdsChange(toggleAccountId(accountIds, account.id))
                }
                className="accent-[var(--primary)]"
              />
              {account.name}
            </label>
          ))}
        </div>
        <span className="text-xs text-[var(--muted-foreground)]">
          {t("reports.filters.accounts.hint")}
        </span>
      </div>
    </div>
  );
}
