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

/**
 * Variants of the `card` element type. Each maps to a Vue file under
 * `src/components/compositions/elements/card/` via the engine registry.
 *
 * `card.*` elements bridge the element/card divide: they act as layout
 * containers that live inline inside any element list. In the FormBuilder,
 * `card.list` is the primary nested canvas — its `elementList` IDs
 * reference entries in the flat schema, enabling drag-and-drop in/out of
 * the container. The other styles wrap their corresponding DisplayCard
 * compositions as element-compatible renderers.
 */
export type CardStyle = "list" | "datatable" | "grid" | "info" | "tab"

export interface CardLayoutElement extends BaseElement<`card.${CardStyle}`> {
  // ── Common ────────────────────────────────────────────────────────────
  title?: string
  subtitle?: string
  showCard?: boolean

  // ── list + tab (nested element containers) ────────────────────────────
  /**
   * Builder-managed child element IDs. Resolved to `nestedElements` by
   * the FormBuilder canvas before being passed to the composition as props.
   */
  elementList?: string[]
  /**
   * Resolved child elements passed by the FormBuilder / engine at render
   * time. Compositions receive this, NOT `elementList`.
   */
  nestedElements?: Array<Record<string, unknown>>
  /** Vertical gap between nested elements. */
  gutterY?: string
  /** Horizontal gap between nested elements. */
  gutterX?: string

  // ── tab ───────────────────────────────────────────────────────────────
  /**
   * For `card.tab` (a tab list): one entry per tab. Each tab is conceptually
   * a "tab container" — a card-list with `style: 'tab-container'` in v1 —
   * and owns its own `elementList` plus tab-container chrome (icon, image,
   * gutters, etc.).
   */
  tabs?: Array<{
    id: string
    label: string
    elementList?: string[]
    /** Icon shown alongside the tab label in the nav. */
    icon?: string
    /** Image shown alongside the tab label in the nav. */
    imageAsset?: string | { id: string; url: string }
    /** Show the surrounding card chrome inside this tab. */
    showCard?: boolean
    /** Allow drag/drop reordering of elements within this tab. */
    draggable?: boolean
    /** Identifier delivered to drop handlers when elements are dragged out. */
    dragTargetData?: string
    /** Vertical gap between this tab's elements. */
    gutterY?: string
    /** Horizontal gap between this tab's elements. */
    gutterX?: string
  }>
  /** Active tab index shown on mount (default 0). */
  activeTab?: number
  /**
   * `card.tab` nav configuration — mirrors `TabListCard`. These round-trip to
   * the v1 `tabs_list` node so a tab container behaves like a TabListCard.
   */
  /** Render the tab nav horizontally along the top. */
  horizontalNav?: boolean
  /** Force the nav bar above the panel content. */
  navOnTop?: boolean
  /** Hide the nav bar entirely. */
  hideNav?: boolean

  // ── datatable ─────────────────────────────────────────────────────────
  /** API endpoint for fetching table rows. */
  dataRoute?: string
  /**
   * Column definitions. Named `tableColumns` to avoid shadowing the
   * responsive-grid `columns` field from `ResponsiveColumns`.
   */
  tableColumns?: Array<{ key: string; label: string; sortable?: boolean }>

  // ── grid ──────────────────────────────────────────────────────────────
  /** Number of CSS-grid columns (default 3). */
  gridCols?: number
  /** Row height in pixels used by the grid layout (default 60). */
  gridRowHeight?: number

  // ── info ──────────────────────────────────────────────────────────────
  /** Icon shown in the card header. */
  icon?: string
  /** Tailwind / CSS colour class for the header icon. */
  iconColor?: string
  /** URL or asset path for a card header image. */
  headerImage?: string
  /** Aspect ratio string for the header image (e.g. `"16/9"`). */
  headerRatio?: string
  /** Reduce internal padding. */
  lessPadding?: boolean
  /** Key/value pairs rendered as read-only rows in the card body. */
  fields?: Array<{
    label: string
    value: string
    icon?: string
    format?: string
    prepend?: string
    append?: string
  }>
}

export const CardLayoutElementDefaults = {
  type: "card.list",
  showCard: true,
  gutterY: "1rem",
  gutterX: "0",
  gridCols: 3,
  gridRowHeight: 60,
  columns: 12,
  columnsSm: 12,
  columnsMd: 12,
  columnsLg: 12,
  columnsXl: 12,
} as const satisfies Partial<CardLayoutElement>

export const CardLayoutElementMetadata = {
  icon: "layout-panel-left",
  displayLabel: "Card / Layout Block",
  elementCategory: "card",
  description:
    "A layout container. Use 'list' to group elements in a card, 'tab' to create a tab list (each tab is its own container), 'info' for display tiles, or 'datatable'/'grid' for structured data.",
} as const satisfies ElementMetadata

export const CardLayoutElementEditConfig = {
  style: {
    type: "option-select.select",
    defaultValue: "list",
    label: "Card Style",
    selectOptions: [
      { label: "List", value: "list" },
      { label: "Tab List", value: "tab" },
      { label: "Info Card", value: "info" },
      { label: "Data Table", value: "datatable" },
      { label: "Grid Layout", value: "grid" },
    ],
    columns: 12,
    section: "layout",
  },
  title: {
    type: "input.text",
    label: "Title",
    columns: 12,
    section: "configuration",
  },
  subtitle: {
    type: "input.text",
    label: "Subtitle",
    columns: 12,
    section: "configuration",
    conditionParams: [{ name: "style", logic: "in-array", value: ["list", "info"] }],
  },
  showCard: {
    type: "boolean.switch",
    defaultValue: true,
    label: "Show Card Chrome",
    columns: 12,
    section: "layout",
    conditionParams: [{ name: "style", logic: "in-array", value: ["list", "tab", "info"] }],
  },
  horizontalNav: {
    type: "boolean.switch",
    label: "Horizontal Tabs",
    columns: 12,
    section: "layout",
    conditionParams: [{ name: "style", logic: "==", value: "tab" }],
  },
  navOnTop: {
    type: "boolean.switch",
    label: "Use Top Navigation",
    columns: 12,
    section: "layout",
    conditionParams: [{ name: "style", logic: "==", value: "tab" }],
  },
  hideNav: {
    type: "boolean.switch",
    label: "Hide Navigation Bar",
    columns: 12,
    section: "layout",
    conditionParams: [{ name: "style", logic: "==", value: "tab" }],
  },
  gutterY: {
    type: "input.text",
    label: "Vertical Gap",
    columns: 6,
    section: "layout",
    conditionParams: [{ name: "style", logic: "in-array", value: ["list", "tab"] }],
  },
  gutterX: {
    type: "input.text",
    label: "Horizontal Gap",
    columns: 6,
    section: "layout",
    conditionParams: [{ name: "style", logic: "in-array", value: ["list", "tab"] }],
  },
  gridCols: {
    type: "input.number",
    label: "Grid Columns",
    columns: 6,
    section: "layout",
    conditionParams: [{ name: "style", logic: "==", value: "grid" }],
  },
  gridRowHeight: {
    type: "input.number",
    label: "Row Height (px)",
    columns: 6,
    section: "layout",
    conditionParams: [{ name: "style", logic: "==", value: "grid" }],
  },
  dataRoute: {
    type: "input.text",
    label: "Data Route",
    columns: 12,
    section: "configuration",
    conditionParams: [{ name: "style", logic: "==", value: "datatable" }],
  },
  icon: {
    type: "picker.icon",
    label: "Header Icon",
    columns: 6,
    section: "configuration",
    conditionParams: [{ name: "style", logic: "==", value: "info" }],
  },
  iconColor: {
    type: "input.text",
    label: "Icon Color",
    columns: 6,
    section: "configuration",
    conditionParams: [{ name: "style", logic: "==", value: "info" }],
  },
  headerImage: {
    type: "file.asset-picker",
    label: "Header Image",
    columns: 12,
    section: "configuration",
    conditionParams: [{ name: "style", logic: "==", value: "info" }],
  },
  headerRatio: {
    type: "input.text",
    label: "Image Aspect Ratio",
    columns: 6,
    section: "layout",
    conditionParams: [{ name: "style", logic: "==", value: "info" }],
  },
  lessPadding: {
    type: "boolean.switch",
    label: "Reduce Padding",
    columns: 6,
    section: "layout",
    conditionParams: [{ name: "style", logic: "==", value: "info" }],
  },
} as const satisfies EditConfig

export const CardStyleMetadataMap: Partial<
  Record<CardStyle, { displayLabel: string; description: string }>
> = {
  list: {
    displayLabel: "List",
    description: "A card containing a vertical list of elements — the primary layout block.",
  },
  tab: {
    displayLabel: "Tab List",
    description:
      "A tab list — a tabbed card where each tab is its own container holding a list of elements.",
  },
  info: {
    displayLabel: "Info Card",
    description: "A display tile with an optional header image/icon and key-value fields.",
  },
  datatable: {
    displayLabel: "Data Table",
    description: "A sortable, paginated data table fetched from an API route.",
  },
  grid: {
    displayLabel: "Grid Layout",
    description: "A CSS-grid canvas for structured multi-column element placement.",
  },
}
