import type {
  BaseElement,
  EditConfig,
  ElementMetadata,
} from "@/definitions/shared/base"
import type { ValidationConfig } from "@/definitions/shared/validation"

/**
 * Variants of the `editor` element type. Each value here maps 1:1 to a
 * Vue file under `src/elements/editor/` via the engine's registry.
 *
 * The v2 schema spells the HTML variant as "html" — we accept both
 * "html" (legacy) and "html-editor" (canonical) by widening the style
 * accordingly. JSON authored against the platform deserialises either way.
 */
export type EditorStyle =
  | "code-editor"
  | "markdown-editor"
  | "html-editor"
  | "image-editor"
  | "rich-text-editor"

export interface EditorElement extends BaseElement<`editor.${EditorStyle}`> {
  name: string
  label: string
  defaultValue?: string | number | null
  /** Help / hint markup rendered above the editor. */
  instructions?: string
  /** CSS height (e.g. "40vh", "320px"). */
  height?: string
  /** For `code-editor`: language hint (e.g. "javascript", "json"). */
  language?: string
  /** Render line numbers (code/markdown editors). */
  showLineNumbers?: boolean
  /** Soft-wrap long lines (code/markdown editors). */
  wordWrap?: boolean
  /** Validation rules (Laravel-style strings). */
  validation?: ValidationConfig
}

export const EditorElementDefaults = {
  type: "editor.code-editor",
  defaultValue: "",
  height: "40vh",
  columns: 12,
  columnsSm: 12,
  columnsMd: 12,
  columnsLg: 12,
  columnsXl: 12,
} as const satisfies Partial<EditorElement>

export const EditorElementMetadata = {
  icon: "file-lines",
  displayLabel: "Editor",
  elementCategory: "editor",
  description:
    "Create a large text field to allow users to enter a large amount of text as either HTML, Markdown, Code or plain text.",
} as const satisfies ElementMetadata

export const EditorElementEditConfig = {
  label: {
    type: "input.text",
    defaultValue: "",
    label: "Label",
    columnsMd: 6,
    columns: 12,
    section: "configuration",
  },
  defaultValue: {
    type: "input.text",
    label: "Default Value",
    columnsMd: 6,
    columns: 12,
    section: "configuration",
  },
  name: {
    type: "picker.data-model",
    defaultValue: "",
    label: "Name",
    columns: 12,
    section: "advanced",
  },
  style: {
    type: "option-select.select",
    defaultValue: "code-editor",
    label: "Display Style",
    section: "layout",
    selectOptions: [
      { label: "Code Editor", value: "code-editor" },
      { label: "Markdown Editor", value: "markdown-editor" },
      { label: "HTML Editor", value: "html-editor" },
      { label: "Image Editor", value: "image-editor" },
      { label: "Rich Text Editor", value: "rich-text-editor" },
    ],
    columns: 12,
  },
  instructions: {
    type: "editor.html-editor",
    label: "Instructions",
    defaultValue: "",
    columns: 12,
    section: "configuration",
  },
  height: {
    type: "input.text",
    label: "Height",
    defaultValue: "40vh",
    columns: 6,
    section: "layout",
  },
  language: {
    type: "input.text",
    label: "Language",
    columns: 6,
    section: "layout",
    conditionParams: [{ name: "style", logic: "==", value: "code-editor" }],
  },
  showLineNumbers: {
    type: "boolean.switch",
    label: "Show line numbers",
    columns: 6,
    section: "layout",
    conditionParams: [
      {
        name: "style",
        logic: "in-array",
        value: ["code-editor", "markdown-editor"],
      },
    ],
  },
  wordWrap: {
    type: "boolean.switch",
    label: "Word wrap",
    columns: 6,
    section: "layout",
    conditionParams: [
      {
        name: "style",
        logic: "in-array",
        value: ["code-editor", "markdown-editor"],
      },
    ],
  },
  required: {
    type: "boolean.switch",
    label: "Make item required",
    columns: 12,
    section: "configuration",
  },
  readonly: {
    type: "boolean.switch",
    label: "Make item read-only",
    columns: 12,
    section: "configuration",
  },
} as const satisfies EditConfig

export const EditorStyleMetadataMap: Partial<Record<EditorStyle, { displayLabel: string; description: string }>> = {
  "code-editor": { displayLabel: "Code Editor", description: "A syntax-highlighted code editor for scripting or config." },
  "markdown-editor": { displayLabel: "Markdown Editor", description: "A live-preview Markdown editor." },
  "html-editor": { displayLabel: "HTML Editor", description: "A WYSIWYG HTML editor with source toggle." },
  "image-editor": { displayLabel: "Image Editor", description: "An in-browser image editor with cropping and filters." },
  "rich-text-editor": { displayLabel: "Rich Text Editor", description: "A Tiptap-powered rich text editor with formatting tools." },
}
