/**
 * Theme Builder — Title & subtitle panel (docs/chart-theming-scope.md §5).
 *
 * The full title block (`config.title.*`), the editorial signature the Type
 * panel couldn't reach: the anchor (left-aligned titles are the FT/Economist
 * hallmark), color, italic, and offset, plus a subtitle group. Title size and
 * weight moved here from the Type panel so every title property sits together;
 * Type keeps font family and the axis type scale.
 *
 * Vega keeps title and subtitle as siblings under `config.title` (subtitle*
 * keys), so both groups write into the one object; each control writes a minimal
 * diff through the shared `useConfigSetter`.
 */

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,
  WeightRow,
} from './ThemeFields';
import type { SelectControlOption } from './SelectControl';

const TEXT_GREY = '#888888';

const ANCHOR: ConfigPath = ['title', 'anchor'];
const COLOR: ConfigPath = ['title', 'color'];
const SIZE: ConfigPath = ['title', 'fontSize'];
const WEIGHT: ConfigPath = ['title', 'fontWeight'];
const STYLE: ConfigPath = ['title', 'fontStyle'];
const OFFSET: ConfigPath = ['title', 'offset'];
const SUB_COLOR: ConfigPath = ['title', 'subtitleColor'];
const SUB_SIZE: ConfigPath = ['title', 'subtitleFontSize'];
const SUB_WEIGHT: ConfigPath = ['title', 'subtitleFontWeight'];
const SUB_STYLE: ConfigPath = ['title', 'subtitleFontStyle'];
const SUB_PADDING: ConfigPath = ['title', 'subtitlePadding'];

// Title `anchor` positions the title across the chart width; "Left" (start) is
// the editorial default a brand most often wants.
type Anchor = '' | 'start' | 'middle' | 'end';
const anchorOptions: SelectControlOption<Anchor>[] = [
  { value: '', label: 'Theme default' },
  { value: 'start', label: 'Left' },
  { value: 'middle', label: 'Center' },
  { value: 'end', label: 'Right' },
];

type FontStyle = '' | 'normal' | 'italic';
const styleOptions: SelectControlOption<FontStyle>[] = [
  { value: '', label: 'Theme default' },
  { value: 'normal', label: 'Normal' },
  { value: 'italic', label: 'Italic' },
];

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

  const sections: AccordionSection[] = [
    {
      id: 'title',
      title: 'Title',
      badge: countSet(config, [ANCHOR, COLOR, SIZE, WEIGHT, STYLE, OFFSET]),
      children: (
        <>
          <SelectRow
            id="title-anchor"
            label="Alignment"
            options={anchorOptions}
            value={enumValue(getConfigValue(config, ANCHOR), anchorOptions)}
            onSelect={(a) => set(ANCHOR, a === '' ? undefined : a)}
          />
          <ColorRow
            label="Color"
            name="Title color"
            value={asString(getConfigValue(config, COLOR))}
            fallback={TEXT_GREY}
            onChange={(hex) => set(COLOR, hex)}
            onClear={() => set(COLOR, undefined)}
          />
          <NumberRow
            label="Size"
            name="Title size"
            value={asNumber(getConfigValue(config, SIZE))}
            min={0}
            unit="px"
            onChange={(n) => set(SIZE, n)}
          />
          <WeightRow
            id="title-weight"
            label="Weight"
            name="Title weight"
            value={getConfigValue(config, WEIGHT)}
            onChange={(w) => set(WEIGHT, w)}
          />
          <SelectRow
            id="title-style"
            label="Style"
            name="Title style"
            options={styleOptions}
            value={enumValue(getConfigValue(config, STYLE), styleOptions)}
            onSelect={(s) => set(STYLE, s === '' ? undefined : s)}
          />
          <NumberRow
            label="Offset"
            name="Title offset"
            value={asNumber(getConfigValue(config, OFFSET))}
            min={0}
            unit="px"
            onChange={(n) => set(OFFSET, n)}
          />
        </>
      ),
    },
    {
      id: 'subtitle',
      title: 'Subtitle',
      hint: 'Styles the subtitle when a spec sets one.',
      badge: countSet(config, [SUB_COLOR, SUB_SIZE, SUB_WEIGHT, SUB_STYLE, SUB_PADDING]),
      children: (
        <>
          <ColorRow
            label="Color"
            name="Subtitle color"
            value={asString(getConfigValue(config, SUB_COLOR))}
            fallback={TEXT_GREY}
            onChange={(hex) => set(SUB_COLOR, hex)}
            onClear={() => set(SUB_COLOR, undefined)}
          />
          <NumberRow
            label="Size"
            name="Subtitle size"
            value={asNumber(getConfigValue(config, SUB_SIZE))}
            min={0}
            unit="px"
            onChange={(n) => set(SUB_SIZE, n)}
          />
          <WeightRow
            id="subtitle-weight"
            label="Weight"
            name="Subtitle weight"
            value={getConfigValue(config, SUB_WEIGHT)}
            onChange={(w) => set(SUB_WEIGHT, w)}
          />
          <SelectRow
            id="subtitle-style"
            label="Style"
            name="Subtitle style"
            options={styleOptions}
            value={enumValue(getConfigValue(config, SUB_STYLE), styleOptions)}
            onSelect={(s) => set(SUB_STYLE, s === '' ? undefined : s)}
          />
          <NumberRow
            label="Gap"
            name="Subtitle gap"
            value={asNumber(getConfigValue(config, SUB_PADDING))}
            min={0}
            unit="px"
            onChange={(n) => set(SUB_PADDING, n)}
          />
        </>
      ),
    },
  ];

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