declare type RequiredPick<T, K extends keyof T> = Partial<T> & Pick<T, K>;

declare interface Image {
  url: string;
  size: number;
}

declare type IOptions = Array<{
  label: string;
  value: any; //[din]
}>;

declare type ILibraryOptions = {
  defaultOptions: {
    options: IOptions;
  };
  scopeOptions?: {
    scope: string;
    options: IOptions;
  };
};

declare interface OssType {
  url: string;
  size: number;
}

declare interface ILibrary {
  id: string;
  defines: IDefine[];
  categories: any[];
}

declare interface IDefine {
  id: string;
  label: string;
  collection: string;
  type: 10 | 20 | 30 | 31 | 40; // 10 模型 20 图片 30 材质球 40 材质球组 50 环境球
  categoryIds: any[];
}

declare interface ISource {
  Mesh: PackageSource;
  Material: IMaterial;
  MaterialGroup: {
    version: string;
    colorCards: IMaterial[];
  };
  Picture: {
    file: Image;
  };
  Env: {
    config: any;
    file: Image;
    options: {
      rotation: number;
      exposure: number;
    };
    toneMap: {
      method: number;
      exposure: number;
      brightness: number;
      contrast: number;
      saturation: number;
    };
  };
  Scene: PackageSource;
}

interface IAssetBase<T extends keyof ISource> {
  _id: string;
  defineId: string;
  taskId: string;

  name: string;
  cusNum: string;

  thumbnail: Image;
  categories: string[];
  cusCategories: string[];
  source: ISource[T];
  assetState: 0 | 100 | 101 | 102 | 200; // 100 等待处理 101 正在处理 102 处理失败 200 处理成功
  enable: boolean;

  userId: string;
  userInfo: {
    name: string;
    thumbnail: OssType;
  };
  ownerId: string;
  ownerType: string;
  assetType: string;

  createTime: string;
  updateTime: string;
}

declare type IAsset = IAssetBase<keyof ISource>;
declare type IAssetMesh = IAssetBase<"Mesh">;
declare type IAssetMat = IAssetBase<"Material">;
declare type IAssetMatGroup = IAssetBase<"MaterialGroup">;
declare type IAssetPic = IAssetBase<"Picture">;
declare type IAssetEnv = IAssetBase<"Env">;
declare type IAssetScene = IAssetBase<"Scene">;

type MatFeature = {
  factor: number;
  color: number[];
  texture: {
    url: string;
    size: number;
  };
  useTexture: boolean;
  enable: boolean;
};

declare type IMaterial = {
  id: string;
  name: string;
  cusNum: string;
  thumbnail: OssType;
  classType: "pbr" | "diamond" | "cuscolor";
  type: "meta" | "spec";
  uvMap: "box" | "uv";
  cullFace: string;
  diamond: Diamond;
  normal: Pick<MatFeature, "factor" | "texture" | "useTexture">;
  metalness: Pick<MatFeature, "factor" | "texture" | "useTexture">;
  roughness: Pick<MatFeature, "factor" | "texture" | "useTexture">;
  gloss: Pick<MatFeature, "factor" | "texture" | "useTexture">;
  albedo: Pick<MatFeature, "color" | "texture" | "useTexture">;
  diffuse: Pick<MatFeature, "color" | "texture" | "useTexture">;
  specular: Pick<MatFeature, "color" | "texture" | "useTexture">;
  displace: Pick<MatFeature, "factor" | "texture" | "useTexture" | "enable">;
  opacity: Pick<MatFeature, "factor" | "texture" | "useTexture" | "enable">;
  uv: MaterailUv;
  cusUv: MaterailUv;
  userData: any;
  from?: MatFrom;

  colorMatch?: any;
  generateType?: "colormatch" | "tech" | undefined;
};

declare class PackageSource {
  version: string;
  mats: PackageMaterial[];
  geoms: PackageGeom[];
  env3ds: PackageEnv3d[];
  products: PackProduct[];
  scenes: PackScene[];
  userData: any;
}

declare class MaterailUv {
  scale: number;
  rotate: number;
  offsetX: number;
  offsetY: number;
}

declare class Diamond {
  scaleX: number;
  scaleY: number;
  brightness: number;
  color: number[];
}

declare type MatFrom = {
  AssetConfId: string;
  MatType: "single" | "group";
  AssetId: string;
};

declare class PackageMaterial {
  id: string;
  name: string;
  cusNum: string;
  thumbnail: OssType;
  type: "meta" | "spec";
  uvMap: "box" | "uv";
  cullFace: string;
  diamond: Diamond;
  normal: Pick<MatFeature, "factor" | "texture" | "useTexture">;
  metalness: Pick<MatFeature, "factor" | "texture" | "useTexture">;
  roughness: Pick<MatFeature, "factor" | "texture" | "useTexture">;
  gloss: Pick<MatFeature, "factor" | "texture" | "useTexture">;
  albedo: Pick<MatFeature, "color" | "texture" | "useTexture">;
  diffuse: Pick<MatFeature, "color" | "texture" | "useTexture">;
  specular: Pick<MatFeature, "color" | "texture" | "useTexture">;
  displace: Pick<MatFeature, "factor" | "texture" | "useTexture" | "enable">;
  opacity: Pick<MatFeature, "factor" | "texture" | "useTexture" | "enable">;
  uv: MaterailUv;
  cusUv: MaterailUv;
  userData: any;
  from?: MatFrom;
}

declare class Obb {
  min: {
    x: number;
    y: number;
    z: number;
  };
  max: {
    x: number;
    y: number;
    z: number;
  };
}
declare class PackageGeom {
  id: string;
  name: string;
  thumbnail: OssType;
  osgjs: OssType;
  file?: OssType;
  glb?: OssType;
  shadow: OssType;
  boundingBox: Obb;
}
declare class Env3dOption {
  rotation: number;
  exposure: number;
}
declare class ToneMap {
  method: number;
  exposure: number;
  brightness: number;
  contrast: number;
  saturation: number;
}

declare class PackageEnv3d {
  id: string;
  name: string;
  cusNum: string;
  thumbnail: OssType;
  createTime: string;
  hdr: OssType;
  config: any;
  options: Env3dOption;
  toneMap: ToneMap;
  background: Evn3dBackground;
  userData: any;
}
declare class PackProductCompMat {
  id: string;
  uvMap: OssType;
  uvsize: {
    width: number;
    height: number;
  };
  name: string;
  matId: string;
  groupId: string;
  index: number;
  visible: boolean;
  userData: any;
  locked: boolean; //当前部件是否被锁定
}
declare class PackProduct {
  id: string;
  geomId: string;
  name: string;
  cusNum: string;
  type: string;
  thumbnail: OssType;
  components: PackProductCompMat[];
  userData: any;
}
declare class PackSceneProduct {
  id: string;
  prodId: string;
  transform: {
    pos: number[];
    scale: number[];
    rotation: number[];
  };
  visible: boolean;
  noShadow: boolean;
}
declare class PackScene {
  id: string;
  name: string;
  thumbnail: OssType;
  envId: string;
  lights: [];
  products: PackSceneProduct[];
  userData: any;
}
