import type {
  BaseElement,
  EditConfig,
  ElementMetadata,
} from "@/definitions/shared/base"
import type { RouteRef } from "@/definitions/shared/route"

/**
 * Variants of the `action` element type. Each value here maps 1:1 to a
 * Vue file under `src/elements/action/` via the engine's registry.
 *
 * Note: the v2 schema spells the group variant as `buttongroup` — we keep
 * that token (so JSON authored against the platform deserialises without
 * translation) and also accept the hyphenated form for new authoring.
 */
export type ActionStyle = "button" | "button-group" | "buttongroup" | "link"

/**
 * Visual variant for `button` / `link` styles. Maps to the design token
 * palette (`--gxp-primary`, `--gxp-secondary`, etc.).
 */
export type ActionVariant =
  | "primary"
  | "secondary"
  | "success"
  | "danger"
  | "warning"
  | "info"
  | "light"
  | "dark"
  | "link"
  | "outline-primary"
  | "outline-secondary"

/**
 * Size token for `button` / `button-group` styles.
 */
export type ActionSize = "sm" | "md" | "lg"

/**
 * A single child action used by the `button-group` style. Mirrors a
 * trimmed-down ActionElement (no recursion / no group-within-group).
 */
export interface ActionGroupItem {
  id?: string
  label: string
  /** Optional lucide icon name rendered before the label. */
  icon?: string
  /** Navigation target. */
  href?: string
  /** Laravel-named route reference (preferred over `href`). */
  route?: RouteRef
  /** Bootstrap-style variant. */
  variant?: ActionVariant
  /** Emit a named event up to the host engine rather than navigating. */
  emit?: string
  disabled?: boolean
}

export interface ActionElement extends BaseElement<`action.${ActionStyle}`> {
  /** Visible label. Required for `button` and `link`; optional for groups. */
  label: string
  /** Optional lucide icon rendered before the label. */
  icon?: string
  /** Bootstrap-style variant (only for `button` / `link`). */
  variant?: ActionVariant
  /** Size token (only for `button` / `button-group`). */
  size?: ActionSize
  /** Render as block (full width). */
  block?: boolean
  /** Navigation target — raw href. */
  href?: string
  /** Open `href` in a new tab. */
  target?: "_self" | "_blank" | "_parent" | "_top"
  /** Laravel-named route reference (preferred over `href`). */
  route?: RouteRef
  /** Emit a named event up to the host engine rather than navigating. */
  emit?: string
  /** Show a confirmation dialog before firing. */
  confirm?: boolean
  /** Confirmation message displayed in the dialog. */
  confirmMessage?: string
  /** For `button-group`: list of child actions. */
  items?: ActionGroupItem[]
}

export const ActionElementDefaults = {
  type: "action.button",
  label: "Action",
  variant: "primary",
  size: "md",
  columns: 12,
  columnsSm: 12,
  columnsMd: 12,
  columnsLg: 12,
  columnsXl: 12,
} as const satisfies Partial<ActionElement>

export const ActionElementMetadata = {
  icon: "bolt",
  displayLabel: "Actions",
  elementCategory: "action",
  description:
    "Create interactive buttons or links that trigger actions when clicked.",
} as const satisfies ElementMetadata

/**
 * EditConfig describes how the FormBuilder inspector renders each
 * configurable property. Each key matches a property on `ActionElement`;
 * the value is a (loosely-typed) element spec.
 */
export const ActionElementEditConfig = {
  style: {
    type: "option-select.select",
    defaultValue: "button",
    label: "Action Style",
    columns: 6,
    selectOptions: [
      { label: "Button", value: "button" },
      { label: "Button Group", value: "button-group" },
      { label: "Link", value: "link" },
    ],
    section: "layout",
  },
  label: {
    type: "input.text",
    defaultValue: "Action",
    label: "Label",
    columns: 12,
    section: "configuration",
  },
  icon: {
    type: "picker.icon",
    label: "Icon",
    columns: 6,
    section: "configuration",
  },
  variant: {
    type: "option-select.select",
    defaultValue: "primary",
    label: "Variant",
    columns: 6,
    selectOptions: [
      { label: "Primary", value: "primary" },
      { label: "Secondary", value: "secondary" },
      { label: "Success", value: "success" },
      { label: "Danger", value: "danger" },
      { label: "Warning", value: "warning" },
      { label: "Info", value: "info" },
      { label: "Light", value: "light" },
      { label: "Dark", value: "dark" },
      { label: "Link", value: "link" },
      { label: "Outline Primary", value: "outline-primary" },
      { label: "Outline Secondary", value: "outline-secondary" },
    ],
    section: "layout",
    conditionParams: [
      { name: "style", logic: "in-array", value: ["button", "link"] },
    ],
  },
  size: {
    type: "option-select.select",
    defaultValue: "md",
    label: "Size",
    columns: 6,
    selectOptions: [
      { label: "Small", value: "sm" },
      { label: "Medium", value: "md" },
      { label: "Large", value: "lg" },
    ],
    section: "layout",
    conditionParams: [
      { name: "style", logic: "in-array", value: ["button", "button-group"] },
    ],
  },
  block: {
    type: "boolean.switch",
    label: "Full Width",
    columns: 6,
    section: "layout",
    conditionParams: [
      { name: "style", logic: "in-array", value: ["button", "button-group"] },
    ],
  },
  href: {
    type: "input.text",
    label: "URL",
    columns: 12,
    section: "configuration",
    conditionParams: [
      { name: "style", logic: "in-array", value: ["button", "link"] },
    ],
  },
  target: {
    type: "option-select.select",
    defaultValue: "_self",
    label: "Link Target",
    columns: 6,
    selectOptions: [
      { label: "Same Tab", value: "_self" },
      { label: "New Tab", value: "_blank" },
      { label: "Parent Frame", value: "_parent" },
      { label: "Top Frame", value: "_top" },
    ],
    section: "configuration",
    conditionParams: [
      { name: "style", logic: "in-array", value: ["button", "link"] },
    ],
  },
  emit: {
    type: "input.text",
    label: "Emit Event Name",
    columns: 6,
    section: "advanced",
    conditionParams: [
      { name: "style", logic: "in-array", value: ["button", "link"] },
    ],
  },
  confirm: {
    type: "boolean.switch",
    label: "Require Confirmation",
    columns: 6,
    section: "configuration",
    conditionParams: [
      { name: "style", logic: "in-array", value: ["button", "link"] },
    ],
  },
  confirmMessage: {
    type: "input.textarea",
    label: "Confirmation Message",
    columns: 12,
    section: "configuration",
    conditionParams: [{ name: "confirm", logic: "==", value: true }],
  },
  items: {
    type: "configuration-block.repeatable",
    label: "Group Items",
    columns: 12,
    section: "configuration",
    conditionParams: [
      { name: "style", logic: "in-array", value: ["button-group", "buttongroup"] },
    ],
  },
} as const satisfies EditConfig

export const ActionStyleMetadataMap: Partial<Record<ActionStyle, { displayLabel: string; description: string }>> = {
  button: { displayLabel: "Button", description: "A clickable button that triggers an action or navigation." },
  "button-group": { displayLabel: "Button Group", description: "A group of related action buttons rendered side-by-side." },
  link: { displayLabel: "Link", description: "An inline hyperlink that navigates or triggers an action." },
}
