'use client';

import {
  BRIEFSTATUS,
  KZK_STATUS,
  KUNDENGROESSE,
  STATUS_DETAIL,
  NEGATIVE_STATUS_CODES,
  type BriefstatusCode,
  type KzkStatusCode,
  type KundengroesseCode,
  type StatusDetailCode,
} from '@/lib/crm/cumas-codes';
import {
  CheckboxGroup,
  CollapsibleSection,
  FilterField,
  FilterHint,
  FilterInput,
  FilterVisibilityPicker,
  SampleSizeBanner,
  SectionLabel,
  StringMultiSelect,
  TriStateToggle,
  useFilterVisibility,
  type DynamicFilterValue,
  type FilterDef,
} from './_shared';
import { SchemaBrowser } from './SchemaBrowser';
import type { ColumnInfo } from '@/lib/crm/cumas-client';

export interface BusinessFilterState {
  server: {
    firma?: string;
    plz?: string;
    strasse?: string;
    email?: string;
    itsAccessId?: number;
    itsNr?: number;
    ksmNr?: number;
    spaNr?: number;
    idkdnr?: number;
  };
  client: {
    itsKsmIn?: string[];
    ortContains?: string;
    brancheContains?: string;
    plzPrefix?: string;
    vshvEigen?: boolean;
    vshvFremd?: boolean;
    resellerIn?: string[];
    briefstatus?: BriefstatusCode[];
    kzkStatus?: KzkStatusCode[];
    kundengroesse?: KundengroesseCode[];
    statusCodes?: StatusDetailCode[];
    excludeNegative?: boolean;
  };
}

export const DEFAULT_BUSINESS_STATE: BusinessFilterState = {
  server: {},
  client: { briefstatus: ['11'], excludeNegative: true },
};

/**
 * Filter-Visibility-Registry. `key` ist die Storage-ID, NICHT der State-Property-Name —
 * mehrere State-Felder können zu einer Visibility-ID gruppiert sein (z.B. `idnumbers`
 * für die ITS-/KSM-/SPA-/idkdnr-Vierer-Gruppe).
 */
const BUSINESS_FILTER_DEFS: FilterDef[] = [
  { key: 'firma', label: 'Firma', group: 'API-Filter' },
  { key: 'email', label: 'Email', group: 'API-Filter', defaultVisible: true },
  { key: 'plz', label: 'PLZ (exakt)', group: 'API-Filter' },
  { key: 'strasse', label: 'Straße', group: 'API-Filter' },
  { key: 'idnumbers', label: 'ITS/KSM/SPA-Nr + idkdnr', group: 'API-Filter' },
  { key: 'its_ksm', label: 'its_ksm', group: 'Klassifizierung', defaultVisible: true },
  { key: 'ort', label: 'Ort', group: 'Klassifizierung' },
  { key: 'plz_prefix', label: 'PLZ-Prefix', group: 'Klassifizierung' },
  { key: 'branche', label: 'Branche', group: 'Klassifizierung' },
  { key: 'reseller', label: 'Reseller', group: 'Klassifizierung' },
  { key: 'briefstatus', label: 'Briefstatus', group: 'Status', defaultVisible: true },
  { key: 'excludeNegative', label: 'Negativ-Kunden ausschließen', group: 'Status', defaultVisible: true },
  { key: 'advanced', label: 'Erweiterte Akquise-Filter', group: 'Status', defaultVisible: true },
  { key: 'schemaBrowser', label: 'Schema-Browser (ad-hoc)', group: 'Erweitert' },
];

export function BusinessFilters({
  state,
  onChange,
  facets,
  facetCounts,
  schemaColumns,
  dynamicFilters,
  onDynamicFiltersChange,
  totalSampled,
  onLoadMoreSamples,
  loadingMoreSamples,
}: {
  state: BusinessFilterState;
  onChange: (next: BusinessFilterState) => void;
  facets: { businessItsKsm: string[]; businessReseller: string[] };
  /** Optional: Counts pro Facet-Key aus dem Schema-Endpoint — rendert "(N)" neben Pills. */
  facetCounts?: { businessItsKsm?: Record<string, number>; businessReseller?: Record<string, number> };
  /** Optional: alle verfügbaren Spalten aus dem Schema-Endpoint (für SchemaBrowser). */
  schemaColumns?: ColumnInfo[];
  dynamicFilters?: DynamicFilterValue[];
  onDynamicFiltersChange?: (next: DynamicFilterValue[]) => void;
  /** Anzahl aktuell gesampleter Datensätze (für SampleSizeBanner). */
  totalSampled?: number;
  /** Callback um eine zusätzliche Sample-Page zu laden. */
  onLoadMoreSamples?: () => void;
  loadingMoreSamples?: boolean;
}) {
  const setServer = (patch: Partial<BusinessFilterState['server']>) =>
    onChange({ ...state, server: { ...state.server, ...patch } });
  const setClient = (patch: Partial<BusinessFilterState['client']>) =>
    onChange({ ...state, client: { ...state.client, ...patch } });

  const numField = (raw: string): number | undefined => {
    if (!raw) return undefined;
    const n = parseInt(raw, 10);
    return isNaN(n) ? undefined : n;
  };

  const { isVisible } = useFilterVisibility('business', BUSINESS_FILTER_DEFS);

  // Section-Sichtbarkeit: SectionLabel nur rendern, wenn mindestens ein Child visible ist.
  const apiVisible = isVisible('firma') || isVisible('email') || isVisible('plz') || isVisible('strasse') || isVisible('idnumbers');
  const klassVisible = isVisible('its_ksm') || isVisible('ort') || isVisible('plz_prefix') || isVisible('branche') || isVisible('reseller');
  const statusVisible = isVisible('briefstatus') || isVisible('excludeNegative') || isVisible('advanced');

  return (
    <div className="space-y-1">
      <FilterVisibilityPicker tabKey="business" defs={BUSINESS_FILTER_DEFS} />

      {totalSampled !== undefined && onLoadMoreSamples && (
        <SampleSizeBanner
          totalSampled={totalSampled}
          loading={loadingMoreSamples ?? false}
          onLoadMore={onLoadMoreSamples}
        />
      )}

      {apiVisible && <SectionLabel>API-Filter (Server-side)</SectionLabel>}
      {isVisible('firma') && (
        <FilterField label="Firma">
          <FilterInput
            value={state.server.firma ?? ''}
            onChange={(v) => setServer({ firma: v || undefined })}
            placeholder="exakt o. Substring"
          />
        </FilterField>
      )}
      {isVisible('email') && (
        <FilterField label="Email">
          <FilterInput
            value={state.server.email ?? ''}
            onChange={(v) => setServer({ email: v || undefined })}
            placeholder="z.B. info@beispiel.de"
          />
        </FilterField>
      )}
      {isVisible('plz') && (
        <FilterField label="PLZ">
          <FilterInput
            value={state.server.plz ?? ''}
            onChange={(v) => setServer({ plz: v || undefined })}
            placeholder="exakt"
          />
        </FilterField>
      )}
      {isVisible('strasse') && (
        <FilterField label="Straße">
          <FilterInput
            value={state.server.strasse ?? ''}
            onChange={(v) => setServer({ strasse: v || undefined })}
            placeholder="Substring"
          />
        </FilterField>
      )}
      {isVisible('idnumbers') && (
        <div className="grid grid-cols-2 gap-1.5">
          <FilterField label="ITS-Nr" layout="stacked">
            <FilterInput
              type="number"
              value={state.server.itsNr?.toString() ?? ''}
              onChange={(v) => setServer({ itsNr: numField(v) })}
              placeholder="Nummer"
            />
          </FilterField>
          <FilterField label="KSM-Nr" layout="stacked">
            <FilterInput
              type="number"
              value={state.server.ksmNr?.toString() ?? ''}
              onChange={(v) => setServer({ ksmNr: numField(v) })}
              placeholder="Nummer"
            />
          </FilterField>
          <FilterField label="SPA-Nr" layout="stacked">
            <FilterInput
              type="number"
              value={state.server.spaNr?.toString() ?? ''}
              onChange={(v) => setServer({ spaNr: numField(v) })}
              placeholder="Nummer"
            />
          </FilterField>
          <FilterField label="idkdnr" layout="stacked">
            <FilterInput
              type="number"
              value={state.server.idkdnr?.toString() ?? ''}
              onChange={(v) => setServer({ idkdnr: numField(v) })}
              placeholder="Cumas-ID"
            />
          </FilterField>
        </div>
      )}

      {klassVisible && <SectionLabel>Klassifizierung (Client-side)</SectionLabel>}
      {isVisible('its_ksm') && (
        <FilterField
          label="its_ksm"
          hint="Multi-Select aus realen Werten · seltene Werte (z.B. SPA, SSPA) manuell hinzufügen"
          layout="stacked"
        >
          <StringMultiSelect
            options={facets.businessItsKsm}
            value={state.client.itsKsmIn ?? []}
            onChange={(v) => setClient({ itsKsmIn: v.length ? v : undefined })}
            counts={facetCounts?.businessItsKsm}
            emptyLabel="Lade Werte..."
            allowCustomAdd
            customAddPlaceholder="z.B. SPA, SSPA, KSM…"
          />
        </FilterField>
      )}
      {isVisible('ort') && (
        <FilterField label="Ort" hint="Substring, case-insensitive">
          <FilterInput
            value={state.client.ortContains ?? ''}
            onChange={(v) => setClient({ ortContains: v || undefined })}
            placeholder="z.B. München"
          />
        </FilterField>
      )}
      {isVisible('plz_prefix') && (
        <FilterField label="PLZ-Prefix" hint="z.B. '8' für Bayern">
          <FilterInput
            value={state.client.plzPrefix ?? ''}
            onChange={(v) => setClient({ plzPrefix: v || undefined })}
            placeholder="z.B. 80"
          />
        </FilterField>
      )}
      {isVisible('branche') && (
        <FilterField label="Branche" hint="Substring">
          <FilterInput
            value={state.client.brancheContains ?? ''}
            onChange={(v) => setClient({ brancheContains: v || undefined })}
            placeholder="z.B. Versicherung"
          />
        </FilterField>
      )}
      {isVisible('reseller') && (
        <FilterField
          label="Reseller"
          hint="Multi-Select aus realen Werten · seltene Werte manuell hinzufügen"
          layout="stacked"
        >
          <StringMultiSelect
            options={facets.businessReseller}
            value={state.client.resellerIn ?? []}
            onChange={(v) => setClient({ resellerIn: v.length ? v : undefined })}
            counts={facetCounts?.businessReseller}
            emptyLabel="Lade Werte..."
            allowCustomAdd
            customAddPlaceholder="z.B. its, spa…"
          />
        </FilterField>
      )}

      {statusVisible && <SectionLabel>Status (Client-side)</SectionLabel>}
      {isVisible('briefstatus') && (
        <FilterField label="Briefstatus (Zoll 2)" hint="Anschreib-Erlaubnis" layout="stacked">
          <CheckboxGroup
            options={BRIEFSTATUS}
            value={(state.client.briefstatus ?? []) as BriefstatusCode[]}
            onChange={(v) => setClient({ briefstatus: v as BriefstatusCode[] })}
          />
        </FilterField>
      )}
      {isVisible('excludeNegative') && (
        <label className="flex items-start gap-2 rounded-md border border-amber-200 bg-amber-50 p-2.5 text-xs dark:border-amber-900/50 dark:bg-amber-950/30">
          <input
            type="checkbox"
            checked={state.client.excludeNegative ?? true}
            onChange={(e) => setClient({ excludeNegative: e.target.checked })}
            className="mt-0.5"
          />
          <div className="flex-1">
            <div className="font-medium text-amber-900 dark:text-amber-200">Negativ-Kunden ausschließen</div>
            <div className="mt-0.5 text-[10px] text-amber-700 dark:text-amber-400">
              Filtert kein Interesse, schlechte Zahler, Inkasso, Klage, Abmahnung, aufgelöst.
            </div>
          </div>
        </label>
      )}
      {isVisible('advanced') && (
        <CollapsibleSection title="Erweiterte Akquise-Filter">
          <FilterField label="KZK-Status" hint="Korrespondenz-Code" layout="stacked">
            <CheckboxGroup
              options={KZK_STATUS}
              value={(state.client.kzkStatus ?? []) as KzkStatusCode[]}
              onChange={(v) => setClient({ kzkStatus: v as KzkStatusCode[] })}
            />
          </FilterField>
          <FilterField label="Kundengröße (70er)" hint="Flotten-Klassifizierung" layout="stacked">
            <CheckboxGroup
              options={KUNDENGROESSE}
              value={(state.client.kundengroesse ?? []) as KundengroesseCode[]}
              onChange={(v) => setClient({ kundengroesse: v as KundengroesseCode[] })}
            />
          </FilterField>
          <FilterField label="Status-Detail-Codes" hint="50–99" layout="stacked">
            <CheckboxGroup
              options={STATUS_DETAIL}
              value={(state.client.statusCodes ?? []) as StatusDetailCode[]}
              onChange={(v) => setClient({ statusCodes: v as StatusDetailCode[] })}
              compact
            />
          </FilterField>
          <TriStateToggle
            label="Versicherungs-Selbstvertrieb (vshv_eigen)"
            value={state.client.vshvEigen}
            onChange={(v) => setClient({ vshvEigen: v })}
          />
          <TriStateToggle
            label="Versicherungs-Fremdvertrieb (vshv_fremd)"
            value={state.client.vshvFremd}
            onChange={(v) => setClient({ vshvFremd: v })}
          />
        </CollapsibleSection>
      )}
      {statusVisible && (
        <FilterHint>
          Status-Codes werden client-seitig aus comment/history/special_features extrahiert (Heuristik). Cumas-API
          listet diese Felder nicht im offiziellen IriTemplate.
        </FilterHint>
      )}

      {/* Phase 3: Schema-Browser für ad-hoc Filter auf zusätzliche Cumas-Spalten.
          Nur sichtbar wenn Parent uns das Schema + Callbacks reicht. */}
      {isVisible('schemaBrowser') && schemaColumns && onDynamicFiltersChange && (
        <SchemaBrowser
          columns={schemaColumns}
          // Excludes = Spalten die schon in den curated Filters abgedeckt sind →
          // user soll sie nicht doppelt im Browser-Mode anbieten bekommen
          excludeColumns={[
            'firma', 'plz', 'strasse', 'email', 'its_ksm', 'reseller',
            'its_nr', 'ksm_nr', 'spa_nr', 'vshv_eigen', 'vshv_fremd',
          ]}
          value={dynamicFilters ?? []}
          onChange={onDynamicFiltersChange}
        />
      )}
    </div>
  );
}

/** Mappt den UI-State auf das API-Body-Schema (mit excludeStatusCodes-Auflösung). */
export function serializeBusinessFilter(s: BusinessFilterState) {
  const client = { ...s.client } as BusinessFilterState['client'] & { excludeStatusCodes?: string[] };
  if (client.excludeNegative) {
    client.excludeStatusCodes = [...NEGATIVE_STATUS_CODES];
  }
  delete (client as { excludeNegative?: boolean }).excludeNegative;
  return { server: s.server, client };
}
