/**
 * Theme Builder — Legend panel (docs/chart-theming-scope.md §5).
 *
 * Structured controls over the base `legend` config: placement, the title's and
 * labels' colour and size, the symbol keys, the continuous gradient bar, and an
 * optional box behind the legend. Legend type (size) lives here rather than the
 * Type panel so every legend property a brand tunes sits together.
 */

import type { JsonObject } from '@core/spec-config';
import {
  asNumber,
  asString,
  type ConfigPath,
  countSet,
  enumValue,
  getConfigValue,
} from '@core/theme-controls';
import { useConfigSetter } from '../stores/CustomThemeStore';
import { Accordion, type AccordionSection, ColorRow, NumberRow, SelectRow } from './ThemeFields';
import type { SelectControlOption } from './SelectControl';

const ORIENT: ConfigPath = ['legend', 'orient'];
const DIRECTION: ConfigPath = ['legend', 'direction'];
const COLUMNS: ConfigPath = ['legend', 'columns'];
const TITLE_COLOR: ConfigPath = ['legend', 'titleColor'];
const TITLE_SIZE: ConfigPath = ['legend', 'titleFontSize'];
const LABEL_COLOR: ConfigPath = ['legend', 'labelColor'];
const LABEL_SIZE: ConfigPath = ['legend', 'labelFontSize'];
const SYMBOL_SIZE: ConfigPath = ['legend', 'symbolSize'];
const SYMBOL_TYPE: ConfigPath = ['legend', 'symbolType'];
const GRADIENT_LENGTH: ConfigPath = ['legend', 'gradientLength'];
const GRADIENT_THICKNESS: ConfigPath = ['legend', 'gradientThickness'];
const FILL_COLOR: ConfigPath = ['legend', 'fillColor'];
const STROKE_COLOR: ConfigPath = ['legend', 'strokeColor'];
const CORNER_RADIUS: ConfigPath = ['legend', 'cornerRadius'];
const PADDING: ConfigPath = ['legend', 'padding'];

const TEXT_GREY = '#888888';

// Vega-Lite legend `orient` values; '' is the unset (theme default) sentinel.
type Orient = '' | 'right' | 'left' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'none';
const orientOptions: SelectControlOption<Orient>[] = [
  { value: '', label: 'Theme default' },
  { value: 'right', label: 'Right' },
  { value: 'left', label: 'Left' },
  { value: 'top', label: 'Top' },
  { value: 'bottom', label: 'Bottom' },
  { value: 'top-left', label: 'Top-left' },
  { value: 'top-right', label: 'Top-right' },
  { value: 'none', label: 'Hidden' },
];

type Direction = '' | 'horizontal' | 'vertical';
const directionOptions: SelectControlOption<Direction>[] = [
  { value: '', label: 'Theme default' },
  { value: 'vertical', label: 'Vertical' },
  { value: 'horizontal', label: 'Horizontal' },
];

// Discrete-legend key shapes (continuous legends render a gradient bar instead).
type SymbolType = '' | 'circle' | 'square' | 'cross' | 'diamond' | 'triangle-up' | 'stroke';
const symbolTypeOptions: SelectControlOption<SymbolType>[] = [
  { value: '', label: 'Theme default' },
  { value: 'circle', label: 'Circle' },
  { value: 'square', label: 'Square' },
  { value: 'cross', label: 'Cross' },
  { value: 'diamond', label: 'Diamond' },
  { value: 'triangle-up', label: 'Triangle' },
  { value: 'stroke', label: 'Line' },
];

export function LegendControls({ config }: { config: JsonObject }) {
  const set = useConfigSetter();

  const sections: AccordionSection[] = [
    {
      id: 'placement',
      title: 'Placement',
      hint: 'Where the legend sits relative to the plot.',
      badge: countSet(config, [ORIENT, DIRECTION, COLUMNS]),
      children: (
        <>
          <SelectRow
            id="legend-orient"
            label="Position"
            options={orientOptions}
            value={enumValue(getConfigValue(config, ORIENT), orientOptions)}
            onSelect={(o) => set(ORIENT, o === '' ? undefined : o)}
          />
          <SelectRow
            id="legend-direction"
            label="Direction"
            options={directionOptions}
            value={enumValue(getConfigValue(config, DIRECTION), directionOptions)}
            onSelect={(d) => set(DIRECTION, d === '' ? undefined : d)}
          />
          <NumberRow
            label="Columns"
            name="Legend columns"
            value={asNumber(getConfigValue(config, COLUMNS))}
            min={0}
            onChange={(n) => set(COLUMNS, n)}
          />
        </>
      ),
    },
    {
      id: 'title',
      title: 'Title',
      badge: countSet(config, [TITLE_COLOR, TITLE_SIZE]),
      children: (
        <>
          <ColorRow
            label="Color"
            name="Legend title color"
            value={asString(getConfigValue(config, TITLE_COLOR))}
            fallback={TEXT_GREY}
            onChange={(hex) => set(TITLE_COLOR, hex)}
            onClear={() => set(TITLE_COLOR, undefined)}
          />
          <NumberRow
            label="Size"
            name="Legend title size"
            value={asNumber(getConfigValue(config, TITLE_SIZE))}
            min={0}
            unit="px"
            onChange={(n) => set(TITLE_SIZE, n)}
          />
        </>
      ),
    },
    {
      id: 'labels',
      title: 'Labels',
      badge: countSet(config, [LABEL_COLOR, LABEL_SIZE]),
      children: (
        <>
          <ColorRow
            label="Color"
            name="Legend label color"
            value={asString(getConfigValue(config, LABEL_COLOR))}
            fallback={TEXT_GREY}
            onChange={(hex) => set(LABEL_COLOR, hex)}
            onClear={() => set(LABEL_COLOR, undefined)}
          />
          <NumberRow
            label="Size"
            name="Legend label size"
            value={asNumber(getConfigValue(config, LABEL_SIZE))}
            min={0}
            unit="px"
            onChange={(n) => set(LABEL_SIZE, n)}
          />
        </>
      ),
    },
    {
      id: 'symbols',
      title: 'Symbols',
      hint: 'The colored keys beside each label.',
      badge: countSet(config, [SYMBOL_TYPE, SYMBOL_SIZE]),
      children: (
        <>
          <SelectRow
            id="legend-symbol-type"
            label="Shape"
            name="Legend symbol shape"
            options={symbolTypeOptions}
            value={enumValue(getConfigValue(config, SYMBOL_TYPE), symbolTypeOptions)}
            onSelect={(t) => set(SYMBOL_TYPE, t === '' ? undefined : t)}
          />
          <NumberRow
            label="Symbol size"
            value={asNumber(getConfigValue(config, SYMBOL_SIZE))}
            min={0}
            unit="px²"
            onChange={(n) => set(SYMBOL_SIZE, n)}
          />
        </>
      ),
    },
    {
      id: 'gradient',
      title: 'Gradient',
      hint: 'The continuous color bar (quantitative legends).',
      badge: countSet(config, [GRADIENT_LENGTH, GRADIENT_THICKNESS]),
      children: (
        <>
          <NumberRow
            label="Length"
            name="Gradient length"
            value={asNumber(getConfigValue(config, GRADIENT_LENGTH))}
            min={0}
            unit="px"
            onChange={(n) => set(GRADIENT_LENGTH, n)}
          />
          <NumberRow
            label="Thickness"
            name="Gradient thickness"
            value={asNumber(getConfigValue(config, GRADIENT_THICKNESS))}
            min={0}
            unit="px"
            onChange={(n) => set(GRADIENT_THICKNESS, n)}
          />
        </>
      ),
    },
    {
      id: 'box',
      title: 'Box',
      hint: 'An optional filled/bordered panel behind the legend.',
      badge: countSet(config, [FILL_COLOR, STROKE_COLOR, CORNER_RADIUS, PADDING]),
      children: (
        <>
          <ColorRow
            label="Fill"
            name="Legend fill"
            value={asString(getConfigValue(config, FILL_COLOR))}
            fallback="#ffffff"
            onChange={(hex) => set(FILL_COLOR, hex)}
            onClear={() => set(FILL_COLOR, undefined)}
          />
          <ColorRow
            label="Border"
            name="Legend border"
            value={asString(getConfigValue(config, STROKE_COLOR))}
            fallback="#cccccc"
            onChange={(hex) => set(STROKE_COLOR, hex)}
            onClear={() => set(STROKE_COLOR, undefined)}
          />
          <NumberRow
            label="Corner radius"
            name="Legend corner radius"
            value={asNumber(getConfigValue(config, CORNER_RADIUS))}
            min={0}
            unit="px"
            onChange={(n) => set(CORNER_RADIUS, n)}
          />
          <NumberRow
            label="Padding"
            name="Legend padding"
            value={asNumber(getConfigValue(config, PADDING))}
            min={0}
            unit="px"
            onChange={(n) => set(PADDING, n)}
          />
        </>
      ),
    },
  ];

  return <Accordion sections={sections} idPrefix="legend" />;
}
