/**
 * Legacy-JSON → composition-prop remapping.
 *
 * The composition layer was refactored to use shadcn-style normalised
 * prop names, but plenty of JSON in the wild still uses the old v2
 * names (`triggerButtonLabel` instead of `triggerLabel`, GxP variant
 * aliases like `"primary"` instead of `"default"`, etc).
 *
 * This module is consulted by `ElementRenderer` after stripping
 * schema-only keys and before spreading the result onto the resolved
 * composition. It's a thin compatibility layer — every entry here is
 * a known legacy form. Renderers themselves stay schema-agnostic.
 *
 * Adding a new alias:
 *   - For a prop-name rename, add to `PROP_RENAMES[<category>]`.
 *   - For a value-only alias (e.g. variant strings), add to
 *     `VALUE_ALIASES[<category>].<prop>`.
 */

/**
 * Per-category prop-name renames. The string on the left is the legacy
 * JSON key; the string on the right is the new composition prop name.
 *
 * Matched against the element's category prefix (`element.type` split
 * at the dot). `*` is a wildcard that applies to every element.
 */
export const PROP_RENAMES: Record<string, Record<string, string>> = {
  "configuration-block": {
    selectOptions: "nestedElements",
    triggerButtonLabel: "triggerLabel",
    dialogTitle: "title",
    modalTitle: "title",
    addOptionButtonLabel: "addButtonLabel",
  },
  display: {
    icon: "iconName",
  },
}

/**
 * Per-(category, prop) value aliases. Used when a prop's accepted value
 * union changed and we want legacy JSON to still resolve. Lookups are
 * case-sensitive; unknown values pass through untouched.
 */
export const VALUE_ALIASES: Record<string, Record<string, Record<string, string>>> = {
  action: {
    variant: {
      primary: "default",
      danger: "destructive",
      "outline-primary": "outline",
      "outline-danger": "outline",
      "outline-secondary": "outline",
      "btn-success": "success",
      "btn-warning": "warning",
      "btn-info": "info",
      light: "ghost",
      dark: "default",
    },
  },
  boolean: {
    variant: {
      // Boolean controls don't have variant aliases yet — reserved.
    },
  },
}

/**
 * Apply prop renames + value aliases for an element. Returns a NEW
 * object — never mutates input. Pass the result through `v-bind`.
 */
export function applyLegacyRemaps(
  type: string,
  props: Record<string, unknown>,
): Record<string, unknown> {
  const dot = type.indexOf(".")
  const category = dot < 0 ? type : type.slice(0, dot)
  const renames = PROP_RENAMES[category]
  const aliases = VALUE_ALIASES[category]
  if (!renames && !aliases) {
    return props
  }

  const out: Record<string, unknown> = {}
  for (const [key, value] of Object.entries(props)) {
    const renamedKey = renames?.[key] ?? key
    // Don't overwrite a key the consumer already provided in the new name.
    if (renamedKey !== key && renamedKey in props) {
      continue
    }
    const aliasMap = aliases?.[renamedKey]
    const aliased =
      typeof value === "string" && aliasMap && aliasMap[value] !== undefined
        ? aliasMap[value]
        : value
    out[renamedKey] = aliased
  }
  return out
}

export const __testing = { PROP_RENAMES, VALUE_ALIASES }
