import { IsArray } from "class-validator";
import { Type } from "class-transformer";
import { CameraModel } from "./camera_model";
import { SceneModelsTypes } from "./scene_models_type";
import { RobotModel } from "./robot_model";
import { SolidModel } from "./solid_model";
import { PointModel } from "./point_model";
import { ZoneModel } from "./zone_model";
import { CoreThreeRepository } from "../repository/core_three_repository";
import { LightModel } from "./light_model";
import { Vector3 } from "three";
import { SceneItems } from "../../features/scene_builder/presentation/scene_builder_store";

export abstract class Instance {
  type: string;
  abstract icon: string;
  @Type(() => Vector3)
  position: Vector3;
  orientation: number[];
  name: string;
  toWebGl = (_coreThreeRepository: CoreThreeRepository) => {};
  update = (_coreThreeRepository: CoreThreeRepository) => {};
}
export class SceneAsset {
  name: string;
  @IsArray()
  @Type(() => Instance, {
    discriminator: {
      property: "type",
      subTypes: [
        { value: SolidModel, name: SceneModelsTypes.SOLID },
        { value: CameraModel, name: SceneModelsTypes.CAMERA },
        { value: RobotModel, name: SceneModelsTypes.ROBOT },
        { value: PointModel, name: SceneModelsTypes.POINT },
        { value: LightModel, name: SceneModelsTypes.LIGHT },
        { value: ZoneModel, name: SceneModelsTypes.ZONE },
      ],
    },
    keepDiscriminatorProperty: true,
  })
  scene: (Instance | SolidModel | CameraModel | RobotModel | PointModel | ZoneModel)[];
  toSceneItems = (): SceneItems[] => {
    return this.scene.map((el) => {
      return {
        fn: () => {},
        name: el.name,
        icon: el.icon,
        isSelected: false,
      };
    });
  };
  getElementByName = <T>(name: string) => this.scene.filter((el) => el.name.isEqual(name)).at(0) as T;
  getAllRobotsTopics = () => this.scene.filter((el) => el.type.isEqual(SceneModelsTypes.ROBOT)).map((el) => el.name);
  getAllCameraTopics = () => {};
  getAllPoints = () => this.scene.filter((el) => el.type.isEqual(SceneModelsTypes.POINT)).map((el) => el.name);
  static newScene = (
    scene: (Instance | SolidModel | CameraModel | RobotModel | PointModel | ZoneModel)[],
    name: string
  ) => {
    const sceneAsset = new SceneAsset();
    sceneAsset.scene = scene;
    sceneAsset.name = name;
    return sceneAsset;
  };
}
