import type { AsukaCameraView } from './camera';
import type { AsukaAssemblyComponentDefinition } from './assembly3d';
import type { AsukaElementVariationParametricControls, AsukaParametricDefinition } from './parametric3d';

export type AsukaElementType = 'standard' | 'product-3d' | string;

export type AsukaProduct3DMaterial = {
  label?: string;
  color?: string;
  textureUrl?: string;
  /** Optional tangent-space normal map layered over the base color texture. */
  normalTextureUrl?: string;
  metallic?: number;
  roughness?: number;
  [key: string]: unknown;
};



export type AsukaProduct3DPart = {
  id: string;
  label?: string;
  /** Mesh ids/names that belong to this logical product part. */
  meshNames?: string[];
  /** Optional material ids/names found on the source model. */
  materialNames?: string[];
  /** Optional explicit material target. Defaults to id, then first meshNames entry. */
  materialTarget?: string;
  editable?: boolean;
  printable?: boolean;
  visible?: boolean;
  locked?: boolean;
  parentPartId?: string;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
};

export type AsukaProduct3DPrintAreaObject = {
  id: string;
  type: 'image' | 'text' | 'design' | string;
  x?: number;
  y?: number;
  width?: number;
  height?: number;
  rotation?: number;
  opacity?: number;
  visible?: boolean;
  locked?: boolean;
  source?: {
    url?: string;
    text?: string;
    svg?: string;
    color?: string;
    fontFamily?: string;
    fontSize?: number;
    [key: string]: unknown;
  };
  price?: number | string;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
};

export type AsukaProduct3DPrintArea = {
  id: string;
  label?: string;
  targetMeshId?: string;
  mode?: 'texture' | 'surface';
  textureSlot?: string;
  edgeWrap?: 'none' | 'horizontal' | 'vertical' | 'both' | string;
  uvBounds?: { x: number; y: number; width: number; height: number };
  canvasSize?: { width: number; height: number };
  objects?: AsukaProduct3DPrintAreaObject[];
  visible?: boolean;
  locked?: boolean;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
};

export type AsukaProduct3DConfig = {
  model?: {
    url?: string;
    format?: 'glb' | 'gltf' | string;
  };
  /** Optional customer-facing preview used by variation cards. */
  previewUrl?: string;
  preview?: { url?: string; [key: string]: unknown };
  /** Variation-level mesh/material id. Top-level product-3d elements keep materials in variations. */
  materialTarget?: string;
  /** Variation-level material overrides. Product/support colors and textures are driven by the active variation. */
  materials?: Record<string, AsukaProduct3DMaterial>;
  /** Logical model sub-parts detected from GLB/glTF meshes or configured manually. */
  parts?: AsukaProduct3DPart[];
  /** Stable 3D print areas rendered as texture slots / UV rectangles on the target mesh. */
  printAreas?: AsukaProduct3DPrintArea[];
  activePrintAreaId?: string | null;
  [key: string]: unknown;
};

export type ElementVariation = {
  id: string;
  name: string;
  /** Stable cross-view key used to map equivalent variations whose local ids or labels differ. */
  syncKey?: string;
  /** Optional preview image URL (png/jpg/svg). Fabric/standard variations use this as their visual payload. */
  image?: string;
  /** Product/support 3D override used by product-3d variations. */
  product3d?: AsukaProduct3DConfig;
  /** @deprecated Legacy thumbnail alias. New editors store media in image. */
  icon?: string;
  /** Optional 3D camera view used when this variation is opened from Elements or Variations. */
  camera?: AsukaCameraView;
  /** Optional extra price for this variation. */
  price?: number | string;
  /** Dynamic Product 3D parameters exposed when this variation/part is opened. */
  parametricControls?: AsukaElementVariationParametricControls;
  /** If true, considered the default/active variation in the editor. */
  active?: boolean;
  /** Nested variations (recursive). */
  variations?: ElementVariation[];
};

export type AsukaElement = {
  /** Element kind. product-3d entries are product/support elements edited by Element Editor. */
  type?: AsukaElementType;
  /** Product/support 3D configuration used by the 3D engine. */
  product3d?: AsukaProduct3DConfig;
  /** Optional product-specific recipe consumed by the generic Product 3D parametric engine. */
  parametric?: AsukaParametricDefinition;
  /** Generic spatial assembly recipe: anchors, collisions, clearances, adjacency and BOM. */
  assembly?: AsukaAssemblyComponentDefinition;

  /** Unique element definition id. */
  id: string;
  /** Logical family id shared by copied elements that should map equivalent variations across views. */
  familyId: string;
  /** User-facing label only. Duplicate names are allowed. */
  name: string;
  category?: string;
  /** Optional element preview image URL (used in the Elements list). */
  image?: string;
  /** @deprecated Legacy thumbnail alias. New editors store media in image. */
  icon?: string;

  /** If true, bring created objects to front. */
  bringToFront?: boolean;

  /** If true, element instances are bound/clipped to the active drawing area. Default: false (free on canvas). */
  allowInDrawingAreas?: boolean;

  /** Fabric flags applied to created instances. */
  selectable?: boolean;
  evented?: boolean;

  /** Optional base price for the element (in addition to variation price). */
  price?: number | string;

  variations: ElementVariation[];


  /** Recursive sub-elements. */
  children?: AsukaElement[];
};

export type ElementInstanceMeta = {
  _asukaElementId?: string;
  _asukaElementFamilyId?: string;
  _asukaElementName?: string;
  _asukaElementVariationId?: string;
  _asukaElementIsInstance?: boolean;
};
