/**
 * 3D 模型相关类型定义
 * Three.js 相关类型和数字人模型配置
 */

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import * as THREE from 'three';
import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js';

export type UUID = string;
export type ColorHex = number;

export type Vec2 = [number, number];
export type Vec3 = [number, number, number];
export type Vec4 = [number, number, number, number];
export type Mat4 = number[]; // length 16

// 类型别名
export type XYZ = Vec3;
export type Matrix4 = Mat4;
export type TCamera = PerspectiveCamera | OrthographicCamera;

/* ===== Root ===== */

export interface ThreeJSON<T> {
  metadata?: {
    version: number;
    type:
      | "Object"
      | "Scene"
      | "Geometry"
      | "Material"
      | "BufferGeometry"
      | "Animation";
    generator: string;
  };

  object?: T;          // 主对象树（通常是 Scene / Object3D）
  geometries?: Geometry[];    // 资源池
  materials?: Material[];
  textures?: Texture[];
  images?: Image[];
  animations?: AnimationClip[];
  
  // OrbitControls specific properties
  useOrbitControl?: boolean;
  enableZoom?: boolean;
  enablePan?: boolean;
  minPolarAngle?: number;
  maxPolarAngle?: number;
  minAzimuthAngle?: number;
  maxAzimuthAngle?: number;
  minDistance?: number;
  maxDistance?: number;
  target?: number[];

  // 某些版本还会出现 fonts/shapes/nodes 等自定义扩展：
  [ext: string]: unknown;
}

/* ===== Object3D 基类 ===== */

export interface Object3DBase {
  uuid: UUID;
  type: string;          // e.g. "Scene" | "Mesh" | "PerspectiveCamera" | "PointLight" | ...
  name?: string;

  // 变换
  matrix?: Mat4;         // 若存在，position/rotation/quaternion/scale 可能不会同时写出
  position?: Vec3;
  rotation?: Vec3;       // Euler (XYZ, radians)
  quaternion?: Vec4;
  scale?: Vec3;
  up?: Vec3;

  // 状态
  visible?: boolean;
  castShadow?: boolean;
  receiveShadow?: boolean;
  frustumCulled?: boolean;
  renderOrder?: number;
  layers?: number;

  userData?: Record<string, unknown>;

  children?: Object3D[]; // 层级
}

/* ===== 具体 Object 类型 ===== */

// ---------- Scene ----------
export interface Scene extends Object3DBase {
  type: "Scene";
  background?: ColorHex | UUID | null; // 颜色或纹理/立方体纹理 uuid
  environment?: UUID | null;           // 环境贴图 uuid
  fog?: Fog | null;                // Fog / FogExp2
}

// ---------- Cameras ----------
export interface Camera extends Object3DBase {
  type:
    | "PerspectiveCamera"
    | "OrthographicCamera"
    | "ArrayCamera"
    | "StereoCamera"; // 少见;通常只会导出前两者
  zoom?: number;
  near?: number;
  far?: number;
  focus?: number;
  fov?: number;        // 视场角
  filmGauge?: number;   // 透视相机可用
  filmOffset?: number;  // 透视相机可用
}

export interface PerspectiveCamera extends Camera {
  type: "PerspectiveCamera";
  fov: number;
  // aspect 通常可选（可由渲染器设置），导出里不一定包含
  aspect?: number;
}

export interface OrthographicCamera extends Camera {
  type: "OrthographicCamera";
  left: number;
  right: number;
  top: number;
  bottom: number;
}

// ---------- Lights ----------
export interface Light extends Object3DBase {
  type:
    | "AmbientLight"
    | "HemisphereLight"
    | "DirectionalLight"
    | "PointLight"
    | "SpotLight"
    | "RectAreaLight";
  color?: ColorHex;
  intensity?: number;
}

export interface AmbientLight extends Light {
  type: "AmbientLight";
}

export interface HemisphereLight extends Light {
  type: "HemisphereLight";
  groundColor?: ColorHex;
  skyColor?: ColorHex;
}

export interface DirectionalLight extends Light {
  type: "DirectionalLight";
  shadow?: LightShadow;
  // 目标通常以 Object3D 形式作为 child 一并导出，也可能出现 target uuid：
  target?: UUID;
}

export interface PointLight extends Light {
  type: "PointLight";
  distance?: number;
  decay?: number;
  shadow?: LightShadow;
}

export interface SpotLight extends Light {
  type: "SpotLight";
  distance?: number;
  angle?: number;
  penumbra?: number;
  decay?: number;
  shadow?: LightShadow;
  target?: UUID;
}

export interface RectAreaLight extends Light {
  type: "RectAreaLight";
  width: number;
  height: number;
}

// 阴影
export interface LightShadow {
  camera?: {
    type?: string; // "PerspectiveCamera" | "OrthographicCamera"
    near?: number;
    far?: number;
    fov?: number;      // 透视
    left?: number;     // 正交
    right?: number;
    top?: number;
    bottom?: number;
  };
  bias?: number;
  normalBias?: number;
  radius?: number;
  mapSize?: [number, number];
  autoUpdate?: boolean;
  needsUpdate?: boolean;
}

// ---------- Mesh / Line / Points / Sprite / Group / Bone ----------
export interface Mesh extends Object3DBase {
  type: "Mesh" | "InstancedMesh" | "SkinnedMesh";
  geometry?: UUID;                 // 引用几何体
  material?: UUID | UUID[];        // 引用材质
  drawMode?: number;               // e.g. TrianglesDrawMode / TriangleStripDrawMode
  morphTargetInfluences?: number[];
  morphTargetDictionary?: Record<string, number>;
  // SkinnedMesh 专属
  bindMode?: "attached" | "detached" | string;
  bindMatrix?: Mat4;
  bindMatrixInverse?: Mat4;
  skeleton?: {
    bones: UUID[];                 // Bone 对象的 uuid 列表
    boneInverses?: Mat4[];         // 可选
  };
}

export interface Line extends Object3DBase {
  type: "Line" | "LineSegments" | "LineLoop";
  geometry?: UUID;
  material?: UUID;
}

export interface Points extends Object3DBase {
  type: "Points";
  geometry?: UUID;
  material?: UUID;
}

export interface Sprite extends Object3DBase {
  type: "Sprite";
  material?: UUID;
  center?: Vec2;
}

export interface Group extends Object3DBase {
  type: "Group";
}

export interface Bone extends Object3DBase {
  type: "Bone";
}

export type Object3D =
  | Scene
  | PerspectiveCamera
  | OrthographicCamera
  | Camera
  | AmbientLight
  | HemisphereLight
  | DirectionalLight
  | PointLight
  | SpotLight
  | RectAreaLight
  | Mesh
  | Line
  | Points
  | Sprite
  | Group
  | Bone
  | (Object3DBase & { [k: string]: unknown }); // 兜底扩展

/* ===== Fog ===== */

export type Fog =
  | { type: "Fog"; color: ColorHex; near: number; far: number }
  | { type: "FogExp2"; color: ColorHex; density: number };

/* ===== Geometry（以 BufferGeometry 为主） ===== */

export interface Geometry {
  uuid: UUID;
  type: string; // "BufferGeometry" | 具体几何类型（BoxGeometry/CylinderGeometry 等）视版本而定
  name?: string;
  data?: BufferGeometryData; // BufferGeometry 底层数据
  // 某些旧版本/手写导出会把参数（parameters）直接放在此处：
  parameters?: Record<string, unknown>;
  [extra: string]: unknown;
}

export interface BufferGeometryData {
  attributes: Record<
    string,
    BufferAttribute | InterleavedBufferAttribute
  >;
  index?: BufferAttribute | InterleavedBufferAttribute;
  morphAttributes?: Record<string, BufferAttribute[]>;
  morphTargetsRelative?: boolean;

  groups?: { start: number; count: number; materialIndex?: number }[];

  boundingBox?: { min: Vec3; max: Vec3 };
  boundingSphere?: { center: Vec3; radius: number };

  drawRange?: { start: number; count: number };
  [extra: string]: unknown;
}

export interface BufferAttribute {
  itemSize: number;
  type: string; // e.g. "Float32Array" | "Uint16Array" ...
  array: number[]; // 导出为普通 number 数组
  normalized?: boolean;
}

export interface InterleavedBufferAttribute {
  itemSize: number;
  type: string;
  data: {
    buffer: number[]; // 展平数据
    stride: number;
    type: string;
  };
  offset: number;
  normalized?: boolean;
}

/* ===== Materials ===== */

export interface MaterialBase {
  uuid: UUID;
  type: string; // "MeshStandardMaterial" | "MeshPhysicalMaterial" | "PointsMaterial" | "LineBasicMaterial" | ...
  name?: string;

  color?: ColorHex;
  opacity?: number;
  transparent?: boolean;
  alphaTest?: number;
  depthTest?: boolean;
  depthWrite?: boolean;
  colorWrite?: boolean;
  side?: number; // FrontSide/BackSide/DoubleSide
  blending?: number;
  blendSrc?: number;
  blendDst?: number;
  blendEquation?: number;
  blendSrcAlpha?: number;
  blendDstAlpha?: number;
  blendEquationAlpha?: number;
  polygonOffset?: boolean;
  polygonOffsetFactor?: number;
  polygonOffsetUnits?: number;
  dithering?: boolean;
  toneMapped?: boolean;
  visible?: boolean;
  vertexColors?: boolean | number; // 新旧差异

  // map/纹理引用（均为纹理 uuid）
  map?: UUID | null;
  alphaMap?: UUID | null;
  aoMap?: UUID | null;
  aoMapIntensity?: number;
  bumpMap?: UUID | null;
  bumpScale?: number;
  normalMap?: UUID | null;
  normalScale?: Vec2;
  displacementMap?: UUID | null;
  displacementScale?: number;
  displacementBias?: number;
  emissive?: ColorHex;
  emissiveIntensity?: number;
  emissiveMap?: UUID | null;
  envMap?: UUID | null;
  envMapIntensity?: number;
  lightMap?: UUID | null;
  lightMapIntensity?: number;
  metalness?: number;
  metalnessMap?: UUID | null;
  roughness?: number;
  roughnessMap?: UUID | null;

  // Physical/Transmission/Sheen/Iridescence/Anisotropy 等（按需出现）
  clearcoat?: number;
  clearcoatRoughness?: number;
  clearcoatNormalMap?: UUID | null;
  clearcoatNormalScale?: Vec2;

  sheen?: number | Vec3;
  sheenColor?: ColorHex;
  sheenRoughness?: number;
  sheenColorMap?: UUID | null;
  sheenRoughnessMap?: UUID | null;

  transmission?: number;
  transmissionMap?: UUID | null;
  thickness?: number;
  thicknessMap?: UUID | null;
  attenuationColor?: ColorHex;
  attenuationDistance?: number;
  ior?: number;

  specularIntensity?: number;
  specularIntensityMap?: UUID | null;
  specularColor?: ColorHex;
  specularColorMap?: UUID | null;

  iridescence?: number;
  iridescenceIOR?: number;
  iridescenceThicknessRange?: Vec2;
  iridescenceThicknessMap?: UUID | null;

  anisotropy?: number;
  anisotropyMap?: UUID | null;
  anisotropyRotation?: number;

  // Shader/Node/Raw/Phong/Lambert/Matcap 等材质的补充字段：
  wireframe?: boolean;
  wireframeLinewidth?: number;
  flatShading?: boolean;
  shininess?: number;
  reflectivity?: number;
  refractionRatio?: number;
  gradientMap?: UUID | null;
  matcap?: UUID | null;

  skinning?: boolean;
  morphTargets?: boolean;
  morphNormals?: boolean;

  defines?: Record<string, unknown>;
  uniforms?: Record<string, unknown>;
  extensions?: Record<string, boolean>;
  glslVersion?: number;

  userData?: Record<string, unknown>;

  [extra: string]: unknown;
}

export type Material = MaterialBase;

/* ===== Textures & Images ===== */

export interface Texture {
  uuid: UUID;
  name?: string;

  image?: UUID | ImageData; // 常见为 image: <image uuid>；DataTexture 会内联 data
  mapping?: number;
  channel?: number;

  wrap?: [number, number]; // [wrapS, wrapT]
  wrapS?: number;
  wrapT?: number;
  magFilter?: number;
  minFilter?: number;
  anisotropy?: number;

  format?: number;
  type?: number;      // 数据类型
  encoding?: number;

  flipY?: boolean;
  premultiplyAlpha?: boolean;

  repeat?: Vec2;
  offset?: Vec2;
  center?: Vec2;
  rotation?: number;
  matrixAutoUpdate?: boolean;

  // 立方体纹理/3D 纹理/视频纹理等会有额外键：
  isRenderTargetTexture?: boolean;
  uvTransform?: number[]; // 某些版本

  userData?: Record<string, unknown>;
  [extra: string]: unknown;
}

export interface ImageFile {
  uuid: UUID;
  url: string; // 外链或相对路径
}

export interface ImageData {
  uuid: UUID;
  data: number[] | string; // DataTexture 可能是 base64 / 数组
  width: number;
  height: number;
  // 可选元信息
  type?: number;
  format?: number;
}

export type Image = ImageFile | ImageData;

/* ===== Animations ===== */

export interface AnimationClip {
  name: string;
  duration: number; // 秒
  tracks: KeyframeTrack[];
  blendMode?: number;
  uuid?: UUID;
}

export interface KeyframeTrack {
  name: string; // 目标路径：e.g. "Bone001.position" / ".quaternion" / "mesh.morphTargetInfluences[Smile]"
  type: string; // e.g. "number", "vector", "quaternion", "color"（或具体 Track 类名）
  times: number[];  // 关键帧时间（秒）
  values: number[]; // 扁平数值
  interpolation?: number; // InterpolateLinear 等
}

/* ===== 方便类型合集 ===== */

export type AnyCamera = PerspectiveCamera | OrthographicCamera | Camera;
export type AnyLight =
  | AmbientLight
  | HemisphereLight
  | DirectionalLight
  | PointLight
  | SpotLight
  | RectAreaLight;

export interface BodyOption {
  // 
  key: string;
  name: string;
  // 前缀
  prefix: string;
  // 后缀
  suffix: string;
}
export interface Body {
  // 主体模型名称
  name: string;
  // 部位描述
  options: BodyOption[];
}
export interface ModelDescription {
  name: string
  model: Object3DBase & { body: Body; rotate?: boolean }
  scene?: Object3DBase
  camera: ThreeJSON<Camera>
  lights: ThreeJSON<Light>[]
  orbitControls: ThreeJSON<OrbitControls>
  gridHelper?: {
    size?: number
    divisions?: number
    color1?: string | number
    color2?: string | number
  }
  debug?: boolean
  dracoPath?: string
}
/**
 * 
模型信息
 */
export interface ModelInfo {
  /** 角色对象 */
  actor: THREE.Group<THREE.Object3DEventMap>;
  /** 场景对象列表 */
  scenes: THREE.Object3D[];
  /** 动画剪辑列表 */
  animations: THREE.AnimationClip[];
  /** 动画混合器 */
  mixer: THREE.AnimationMixer;
  /** 动画动作列表 */
  actions: any[];
}

/**
 * 动画播放选项
 */
export interface PlayActionOptions {
  /** 循环模式 */
  loop?: THREE.AnimationActionLoopStyles;
  /** 重复次数 */
  repetitions?: number;
  /** 过渡时间（秒），默认 0.5 */
  fadeDuration?: number;
}

/**
 * 加载器响应
 */
export interface LoaderResponse {
  /** 模型 ID */
  id: string;
  /** 模型名称 */
  name: string;
  /** 模型代码 */
  code: string;
  /** 模型文件路径 */
  bundle: string;
  /** 模型类型 */
  type: 'apose' | 'animation' | 'animation_system';
  /** 是否启用 */
  enabled?: boolean;
  /** 缓冲数据 */
  buffer?: any;
  /** GLTF 对象 */
  gltf?: GLTF;
}

/**
 * 加载进度
 */
export interface LoaderProgress {
  /** 资源 URL */
  url: string;
  /** 进度值 (0-1) */
  progress: number;
  /** 数据总量（字节）或百分比 */
  total: number;
}

/**
 * 模型文件
 */
export interface ModelFile {
  /** 文件名 */
  name: string;
  /** 文件类型 */
  type: 'zip' | 'bundle' | 'glb' | '';
  /** 解压密码（zip 类型） */
  pwd?: string;
  /** 文件路径 */
  url: string;
}

/**
 * 场景类型
 */
export type SceneType = 'hdr' | 'picture' | 'glb' | 'background' | 'video';

/**
 * 场景配置
 */
export interface SceneConfig {
  /** 场景 ID */
  id: string;
  /** 场景名称 */
  name: string;
  /** 场景路径 */
  path: string;
  /** 场景类型 */
  type: SceneType;
  /** 图片列表 */
  pictures?: string[];
  /** 背景 */
  background?: string;
}
