/**
 * Public barrel for every CardElement category.
 *
 * Each category exports four artifacts:
 *   - `<Category>Element` interface (the JSON shape)
 *   - `<Category>Style` union (the `style` discriminator's possible values)
 *   - `<Category>ElementDefaults` const (used by FormBuilder + adapters)
 *   - `<Category>ElementMetadata` const (palette label, icon, description)
 *   - `<Category>ElementEditConfig` const (the FormBuilder inspector schema)
 *
 * The `CardElement` union below is the JSON shape of any element. The
 * engine's `ElementRenderer` accepts a `CardElement` and uses `type`
 * (+ `style`) to resolve the renderer component.
 */

export type {
  ActionElement,
  ActionGroupItem,
  ActionSize,
  ActionStyle,
  ActionVariant,
} from "./ActionElement"
export {
  ActionElementDefaults,
  ActionElementEditConfig,
  ActionElementMetadata,
} from "./ActionElement"

export type { BooleanElement, BooleanStyle } from "./BooleanElement"
export {
  BooleanElementDefaults,
  BooleanElementEditConfig,
  BooleanElementMetadata,
} from "./BooleanElement"

export type { CardLayoutElement, CardStyle } from "./CardLayoutElement"
export {
  CardLayoutElementDefaults,
  CardLayoutElementEditConfig,
  CardLayoutElementMetadata,
  CardStyleMetadataMap,
} from "./CardLayoutElement"

export type { BuilderElement, BuilderStyle } from "./BuilderElement"
export {
  BuilderElementDefaults,
  BuilderElementEditConfig,
  BuilderElementMetadata,
} from "./BuilderElement"

export type { CodeElement, CodeStyle } from "./CodeElement"
export {
  CodeElementDefaults,
  CodeElementEditConfig,
  CodeElementMetadata,
} from "./CodeElement"

export type {
  ConfigurationBlockElement,
  ConfigurationBlockStyle,
} from "./ConfigurationBlockElement"
export {
  ConfigurationBlockElementDefaults,
  ConfigurationBlockElementEditConfig,
  ConfigurationBlockElementMetadata,
} from "./ConfigurationBlockElement"

export type {
  DisplayContentType,
  DisplayElement,
  DisplayStyle,
} from "./DisplayElement"
export {
  DisplayElementDefaults,
  DisplayElementEditConfig,
  DisplayElementMetadata,
} from "./DisplayElement"

export type { EditorElement, EditorStyle } from "./EditorElement"
export {
  EditorElementDefaults,
  EditorElementEditConfig,
  EditorElementMetadata,
} from "./EditorElement"

export type { FileElement, FileStyle } from "./FileElement"
export {
  FileElementDefaults,
  FileElementEditConfig,
  FileElementMetadata,
} from "./FileElement"

export type {
  InputContentType,
  InputElement,
  InputStyle,
} from "./InputElement"
export {
  InputElementDefaults,
  InputElementEditConfig,
  InputElementMetadata,
} from "./InputElement"

export type {
  OptionSelectElement,
  OptionSelectStyle,
} from "./OptionSelectElement"
export {
  OptionSelectElementDefaults,
  OptionSelectElementEditConfig,
  OptionSelectElementMetadata,
} from "./OptionSelectElement"

export type {
  ColorPickerFormat,
  PickerElement,
  PickerStyle,
} from "./PickerElement"
export {
  PickerElementDefaults,
  PickerElementEditConfig,
  PickerElementMetadata,
} from "./PickerElement"

import type { ActionElement } from "./ActionElement"
import type { BooleanElement } from "./BooleanElement"
import type { BuilderElement } from "./BuilderElement"
import type { CardLayoutElement } from "./CardLayoutElement"
import type { CodeElement } from "./CodeElement"
import type { ConfigurationBlockElement } from "./ConfigurationBlockElement"
import type { DisplayElement } from "./DisplayElement"
import type { EditorElement } from "./EditorElement"
import type { FileElement } from "./FileElement"
import type { InputElement } from "./InputElement"
import type { OptionSelectElement } from "./OptionSelectElement"
import type { PickerElement } from "./PickerElement"

import { ActionElementEditConfig, ActionElementMetadata, ActionStyleMetadataMap } from "./ActionElement"
import { BooleanElementEditConfig, BooleanElementMetadata, BooleanStyleMetadataMap } from "./BooleanElement"
import { BuilderElementEditConfig, BuilderElementMetadata, BuilderStyleMetadataMap } from "./BuilderElement"
import { CardLayoutElementEditConfig, CardLayoutElementMetadata, CardStyleMetadataMap } from "./CardLayoutElement"
import { CodeElementEditConfig, CodeElementMetadata, CodeStyleMetadataMap } from "./CodeElement"
import { ConfigurationBlockElementEditConfig, ConfigurationBlockElementMetadata, ConfigurationBlockStyleMetadataMap } from "./ConfigurationBlockElement"
import { DisplayElementEditConfig, DisplayElementMetadata, DisplayStyleMetadataMap } from "./DisplayElement"
import { EditorElementEditConfig, EditorElementMetadata, EditorStyleMetadataMap } from "./EditorElement"
import { FileElementEditConfig, FileElementMetadata, FileStyleMetadataMap } from "./FileElement"
import { InputElementEditConfig, InputElementMetadata, InputStyleMetadataMap } from "./InputElement"
import { OptionSelectElementEditConfig, OptionSelectElementMetadata, OptionSelectStyleMetadataMap } from "./OptionSelectElement"
import { PickerElementEditConfig, PickerElementMetadata, PickerStyleMetadataMap } from "./PickerElement"
import type { EditConfig } from "@/definitions/shared/base"

/**
 * The discriminated-union JSON shape of any CardElement. Narrowing on
 * `type` gives full intellisense for the style-specific fields.
 */
export type CardElement =
  | CardLayoutElement
  | DisplayElement
  | InputElement
  | BooleanElement
  | OptionSelectElement
  | PickerElement
  | FileElement
  | EditorElement
  | ConfigurationBlockElement
  | ActionElement
  | BuilderElement
  | CodeElement


/**
 * Runtime registry of element metadata keyed by `type`. Used by the
 * FormBuilder palette to enumerate available elements.
 */
export const CardElementMetadataMap = {
  card: CardLayoutElementMetadata,
  display: DisplayElementMetadata,
  input: InputElementMetadata,
  boolean: BooleanElementMetadata,
  "option-select": OptionSelectElementMetadata,
  picker: PickerElementMetadata,
  file: FileElementMetadata,
  editor: EditorElementMetadata,
  "configuration-block": ConfigurationBlockElementMetadata,
  action: ActionElementMetadata,
  builder: BuilderElementMetadata,
  code: CodeElementMetadata,
} as const

/** Registry of all per-style metadata maps, keyed by element category. */
export const CategoryStyleMetadataMaps = {
  card: CardStyleMetadataMap,
  display: DisplayStyleMetadataMap,
  input: InputStyleMetadataMap,
  boolean: BooleanStyleMetadataMap,
  "option-select": OptionSelectStyleMetadataMap,
  picker: PickerStyleMetadataMap,
  file: FileStyleMetadataMap,
  editor: EditorStyleMetadataMap,
  "configuration-block": ConfigurationBlockStyleMetadataMap,
  action: ActionStyleMetadataMap,
  builder: BuilderStyleMetadataMap,
  code: CodeStyleMetadataMap,
} as const

function deriveStyles(
  map: Partial<Record<string, { displayLabel: string; description: string }>>,
): ReadonlyArray<{ value: string; label: string }> {
  return Object.entries(map)
    .filter((entry): entry is [string, { displayLabel: string; description: string }] => entry[1] != null)
    .map(([value, meta]) => ({ value, label: meta.displayLabel }))
}

/**
 * All style variants per element category, derived from each category's
 * StyleMetadataMap. Adding a new style only requires updating the category's
 * definition file — no changes needed here.
 */
export const CardElementStylesMap = {
  card: deriveStyles(CardStyleMetadataMap),
  display: deriveStyles(DisplayStyleMetadataMap),
  input: deriveStyles(InputStyleMetadataMap),
  boolean: deriveStyles(BooleanStyleMetadataMap),
  "option-select": deriveStyles(OptionSelectStyleMetadataMap),
  picker: deriveStyles(PickerStyleMetadataMap),
  file: deriveStyles(FileStyleMetadataMap),
  editor: deriveStyles(EditorStyleMetadataMap),
  "configuration-block": deriveStyles(ConfigurationBlockStyleMetadataMap),
  action: deriveStyles(ActionStyleMetadataMap),
  builder: deriveStyles(BuilderStyleMetadataMap),
  code: deriveStyles(CodeStyleMetadataMap),
} satisfies Record<keyof typeof CardElementMetadataMap, ReadonlyArray<{ value: string; label: string }>>

/**
 * EditConfig for every element category, keyed by category name.
 * Used by the FormBuilder inspector to render element-specific fields.
 */
export const CategoryEditConfigMap = {
  card: CardLayoutElementEditConfig,
  display: DisplayElementEditConfig,
  input: InputElementEditConfig,
  boolean: BooleanElementEditConfig,
  "option-select": OptionSelectElementEditConfig,
  picker: PickerElementEditConfig,
  file: FileElementEditConfig,
  editor: EditorElementEditConfig,
  "configuration-block": ConfigurationBlockElementEditConfig,
  action: ActionElementEditConfig,
  builder: BuilderElementEditConfig,
  code: CodeElementEditConfig,
} as const

/**
 * Look up the EditConfig for a dot-notation element type (e.g. `"input.text"`).
 * Returns the category-level EditConfig whose `conditionParams` narrow which
 * fields are visible for the specific style.
 */
export function getElementEditConfig(type: string): EditConfig | undefined {
  const category = type.split(".")[0] as keyof typeof CategoryEditConfigMap
  return CategoryEditConfigMap[category] as EditConfig | undefined
}
