/**
 * Condition / visibility evaluation contract.
 *
 * Matches the existing v2 Mod schema:
 *   conditionParams: [{ name: "first_name", logic: "!=", value: "" }]
 *
 * The engine ANDs (default) or ORs (per `conditionGroupLogic`) every
 * entry. Nested groups are expressed by passing `subCondition: true`
 * and providing a nested `conditionParams` array on that entry.
 *
 * The v1 schema used `{field, operator, value}` — the v1 adapter
 * renames those keys before handing the element to the engine.
 */
export type ConditionLogic =
  | "=="
  | "!="
  | ">"
  | ">="
  | "<"
  | "<="
  | "in-array"
  | "not-in-array"
  | "starts-with"
  | "ends-with"
  | "contains"
  | "not-contains"
  | "matches"
  | "is-odd"
  | "is-even"
  | "is-truthy"
  | "is-falsy"
  | "is-null"
  | "is-not-null"
  | "g0length"
  | "n0length"
  | "length-eq-value"
  | "length-gt-value"
  | "length-lt-value"
  | "zero-length"

export type ConditionGroupLogic = "AND" | "OR"

export interface ConditionParam {
  /** Dot-path into the data model. e.g. `"user.role"`. */
  name: string
  logic: ConditionLogic
  /** Comparison value. Optional for unary operators. */
  value?: unknown
  /** Type hint for `value` — "string" (literal) or "model" (data path). */
  valueType?: "string" | "model"
  /** When true, this entry is itself a nested group with its own params. */
  subCondition?: boolean
  /** Logic for the nested group (only meaningful when subCondition). */
  conditionGroupLogic?: ConditionGroupLogic
  /** Nested params (only meaningful when subCondition). */
  conditionParams?: ConditionParam[]
}

export type ConditionFn<TItem = Record<string, unknown>> = (
  item: TItem,
) => boolean

export interface Conditional<TItem = Record<string, unknown>> {
  /** Function predicate. Wins over `conditionParams` when both are set. */
  condition?: ConditionFn<TItem>
  /** Declarative predicates, AND-combined unless `conditionGroupLogic` says OR. */
  conditionParams?: ConditionParam[]
  conditionGroupLogic?: ConditionGroupLogic
  /** Feature flags required for this element/card to render. */
  features?: string[]
  /** Permissions required for this element/card to render. */
  permissions?: string[]
}

/**
 * Aliases accepted by the v1 adapter. v1 JSON used `field`/`operator`;
 * the adapter renames before evaluation.
 */
export interface ConditionParamV1 {
  field: string
  operator: string
  value?: unknown
}
