export type RawEnum = { rawValue?: number; name?: string; knownValue?: boolean };
export type Vec2Raw = [number, number];
export type Vec3Raw = [number, number, number];
export type MatrixRows = number[][];

export interface OriginEffectTextureSlot {
  slot?: string;
  assetUrl?: string;
  assetStatus?: string;
  sourceTexturePath?: string;
  sourceTextureSha256?: string;
  uvSetRaw?: number;
  clampMode?: RawEnum;
  filterMode?: RawEnum;
  staticTextureTransform?: {
    translationRaw?: number[];
    scaleRaw?: number[];
    rotationRaw?: number;
    centerRaw?: number[];
  } | null;
  texture?: {
    previewAsset?: { status?: string; url?: string; sha256?: string };
  };
}

export interface OriginEffectKey {
  time?: number;
  value?: number | null;
  forward?: number | null;
  backward?: number | null;
  valueRaw?: number[] | null;
  forwardRaw?: number[] | null;
  backwardRaw?: number[] | null;
  tbc?: number[] | null;
}

export interface OriginEffectController {
  type?: string;
  controllerBlockIndex?: number;
  targetBlockIndex?: number;
  targetType?: string;
  basePropertyBlockIndex?: number;
  kind?: string;
  flags?: {
    flagsRaw?: number;
    cycleType?: RawEnum;
    active?: boolean;
    playBackwards?: boolean;
    computeScaledTime?: boolean;
  };
  frequencyRaw?: number;
  phaseRaw?: number;
  startTimeRaw?: number;
  stopTimeRaw?: number;
  operation?: RawEnum;
  textureSlot?: RawEnum;
  targetColor?: RawEnum;
  interpolationType?: RawEnum;
  keys?: OriginEffectKey[];
  runtimeStatus?: string;
}

export interface OriginEffectProperty {
  blockIndex?: number;
  ownerBlockIndex?: number;
  scope?: string;
  type?: string;
  flagsRaw?: number;
  alphaBlend?: boolean;
  sourceBlendMode?: RawEnum;
  destinationBlendMode?: RawEnum;
  alphaTest?: boolean;
  testFunction?: RawEnum;
  thresholdRaw?: number;
  ambientColorRaw?: number[];
  diffuseColorRaw?: number[];
  emissiveColorRaw?: number[];
  emissiveMultRaw?: number;
  alphaRaw?: number;
  colorModeRaw?: number;
  vertexMode?: RawEnum;
  lightingMode?: RawEnum;
  depthTest?: boolean;
  depthWrite?: boolean;
  compareFunction?: RawEnum;
  applyMode?: RawEnum;
  slots?: OriginEffectTextureSlot[];
}

export interface OriginEffectMesh {
  skinned?: boolean;
  sourceSkinRequired?: boolean;
  blockIndex?: number;
  meshId?: string;
  name?: string;
  type?: string;
  sourcePath?: string;
  sourceMatrixWorldRows?: MatrixRows;
  positionsNifUnits?: number[][];
  triangleIndices?: number[][];
  normalsNif?: number[][];
  uv0Raw?: number[][];
  vertexColorsRaw?: number[][];
  properties?: OriginEffectProperty[];
  inheritedProperties?: OriginEffectProperty[];
  textures?: { blockIndex?: number; slots?: OriginEffectTextureSlot[] }[];
  controllers?: OriginEffectController[];
  ancestorNodes?: {
    type?: string;
    blockIndex?: number;
    avObjectFlagsRaw?: number;
    hiddenBit0SetRaw?: boolean;
    hidden?: boolean | null;
    hiddenStatus?: string;
    billboardMode?: RawEnum;
    renderingStatus?: string;
  }[];
  viewerRenderable?: boolean;
  isParticleEmitterMesh?: boolean;
  diagnostics?: unknown[];
}

export interface OriginEffectModel {
  id: string;
  source?: { path?: string; sha256?: string; blockCount?: number };
  candidateMeshes?: OriginEffectMesh[];
  particleSystems?: unknown[];
  diagnostics?: unknown[];
  association?: unknown;
  itemIds?: string[];
  appearanceCodes?: string[];
}

export interface OriginEffectsCatalog {
  schemaVersion?: string;
  clientId?: string;
  coordinateConversion?: Record<string, unknown>;
  semanticBoundary?: Record<string, unknown>;
  weapons?: OriginEffectModel[];
  relatedModels?: OriginEffectModel[];
}

export interface OriginEffectBinding {
  instanceKey: string;
  effectId: string;
  target: import('three').Object3D;
  provenance?: unknown;
}

export interface OriginEffectReceiptBinding {
  instanceKey: string;
  effectId: string;
  targetName: string;
  status: 'ATTACHED' | 'NO_EXTRACTED_MODEL' | 'NO_RENDERABLE_MESHES' | 'LOAD_FAILED' | 'CANCELLED';
  provenance?: unknown;
  source: { path: string | null; sha256: string | null };
  runtime?: {
    sourceSha256: string; pathControllerBlocks: number[]; billboardMeshBlocks: number[];
    elapsedSeconds: number; engineAppearanceParityValidated: false;
    simulatedParticleSystemBlocks?: number[]; liveParticleCount?: number; particleDiagnostics?: string[];
    particleMaterials?: { systemBlock: number; textureUrl: string; depthTest: boolean; depthWrite: boolean;
      intensity: number; effectivePropertyBlocks: { type: string; blockIndex: number | null }[];
      materialAudit?: { sourceVertexMode: number; lightingMode: number; vertexColorsEnabled: number;
        diffuseColor: number[]; emissiveColor: number[]; emissiveMultiplier: number; opacity: number;
        sourceBlendMode: number | null; destinationBlendMode: number | null; textureColorSpace: string;
        alphaBlend: boolean; canvasAlphaPolicy: string; alphaTestEnabled: number; diffuseLightingApproximation: string;
        diffuseContribution: number;
        textureLayers: { slot: string; textureUrl: string; uvSet: number; rgbScale: number; alphaScale: number }[] } }[];
  };
  sizeAdjustment?: {
    scale: number;
    pivot: 'RENDERED_FX_BOUNDS_CENTER';
    centerLocal: number[];
    sourceBoundsSize: number[];
    previewBoundsSize: number[];
    previewCenterLocal: number[];
  };
  meshes: {
    blockIndex: number | null;
    name: string;
    status: 'RENDERED' | 'SKIPPED' | 'FAILED';
    textureUrls: string[];
    animatedControllers: number;
    diagnostics: string[];
  }[];
  unsupported: string[];
  diagnostics: string[];
}

export interface OriginEffectPreviewSettings {
  effectFramesPerSecond: number;
  calibrationProfileRevision: string;
  intensity: number;
  effectScale: number;
  effectScalePivot: 'RENDERED_FX_BOUNDS_CENTER';
  sourceGeometryScaleChanged: false;
  sourceMaterialValuesChanged: false;
  engineAppearanceParityValidated: false;
}

export interface OriginEffectReceipt {
  schemaVersion: 'gf-origin-effect-receipt/1';
  previewSettings: OriginEffectPreviewSettings;
  manifestSourceURL: string;
  clientId: string | null;
  cancelled: boolean;
  summary: string;
  stats: {
    requestedBindings: number;
    attachedBindings: number;
    renderedMeshes: number;
    animatedControllers: number;
    unsupportedControllers: number;
    unsupportedParticles: number;
    simulatedParticleSystems?: number;
    failedMeshes: number;
  };
  bindings: OriginEffectReceiptBinding[];
}

