// FacetGroups.jsx — §22.4a SLICE-3 faceted left-pane filters (§5.1).
//
// Renders one collapsible group per facet field returned by the API, each with
// per-value result counts and multi-select checkboxes. A `tags`-type field gets
// a "filter values…" search box so it stays usable at 30+ values. Selection
// state + the malformed toggle are owned by the parent (Catalog), which
// re-fetches server-side on change.

import { useState } from 'react'

// Human label for the built-in state facet; declared fields use their own name
// (or the schema `label` when the API supplies it on `fields`).
function groupLabel(field, fields) {
  if (field === 'state') return 'State'
  const def = fields?.[field]
  return def?.label || field.charAt(0).toUpperCase() + field.slice(1)
}

function FacetGroup({ field, fields, counts, selected, onToggle, isTags }) {
  const [open, setOpen] = useState(true)
  const [valueSearch, setValueSearch] = useState('')
  const entries = Object.entries(counts).sort((a, b) => b[1] - a[1])
  const needle = valueSearch.trim().toLowerCase()
  const shown = isTags && needle
    ? entries.filter(([v]) => v.toLowerCase().includes(needle))
    : entries
  return (
    <div className="facet-group">
      <button className="facet-header" onClick={() => setOpen(o => !o)}>
        <span>{open ? '▾' : '▸'} {groupLabel(field, fields)}</span>
      </button>
      {open && (
        <div className="facet-values">
          {isTags && entries.length > 8 && (
            <input
              className="facet-value-search"
              placeholder="filter values…"
              value={valueSearch}
              onChange={e => setValueSearch(e.target.value)}
            />
          )}
          {shown.length === 0 && (
            <div className="facet-empty">No values.</div>
          )}
          {shown.map(([value, count]) => (
            <label key={value} className="facet-value">
              <input
                type="checkbox"
                checked={selected.has(value)}
                onChange={() => onToggle(field, value)}
              />
              <span className="facet-value-label">{value}</span>
              <span className="facet-count">{count}</span>
            </label>
          ))}
        </div>
      )}
    </div>
  )
}

export default function FacetGroups({
  facets, fields, selections, onToggle, malformedOnly, onToggleMalformed,
  onClear, hasActiveFilters,
}) {
  // The API returns facets in field order with `state` last; render in that
  // order. `selections` is { field: Set<string> }.
  const fieldOrder = Object.keys(facets || {})
  // A `tags`-type field renders the value-search box.
  const isTags = (field) => fields?.[field]?.type === 'tags'
  return (
    <div className="facets">
      {hasActiveFilters && (
        <button className="facet-clear" onClick={onClear}>Clear filters</button>
      )}
      {fieldOrder.map(field => (
        <FacetGroup
          key={field}
          field={field}
          fields={fields}
          counts={facets[field]}
          selected={selections[field] || new Set()}
          onToggle={onToggle}
          isTags={isTags(field)}
        />
      ))}
      <label className="facet-malformed">
        <input
          type="checkbox"
          checked={malformedOnly}
          onChange={onToggleMalformed}
        />
        <span>Malformed metadata only</span>
      </label>
    </div>
  )
}
