// Base Types
interface AssetEventSchema {
    modelUuid: string;
    modelName: string;
    position: [number, number, number];
    rotation: [number, number, number];
    state: "idle" | "running" | "stopped" | "disabled" | "error";
}

interface TriggerSchema {
    triggerUuid: string;
    triggerName: string;
    triggerType: "onComplete" | "onStart" | "onStop" | "delay" | "onError";
    delay: number;
    triggeredAsset: {
        triggeredModel: { modelName: string, modelUuid: string };
        triggeredPoint: { pointName: string, pointUuid: string } | null;
        triggeredAction: { actionName: string, actionUuid: string } | null;
    } | null;
}

// Actions
interface ConveyorAction {
    actionUuid: string;
    actionName: string;
    actionType: "default" | "spawn" | "swap" | "delay" | "despawn";
    material: string;
    delay: number;
    spawnInterval: number;
    spawnCount: number;
    triggers: TriggerSchema[];
}

interface VehicleAction {
    actionUuid: string;
    actionName: string;
    actionType: "travel";
    unLoadDuration: number;
    loadCapacity: number;
    steeringAngle: number;
    pickUpPoint: { position: { x: number; y: number, z: number }, rotation: { x: number; y: number, z: number } } | null;
    unLoadPoint: { position: { x: number; y: number, z: number }, rotation: { x: number; y: number, z: number } } | null;
    paths: {
        initPickup: {
            pointId: string;
            position: [number, number, number];
            isCurved: boolean;
            handleA: [number, number, number] | null;
            handleB: [number, number, number] | null;
        }[],
        pickupDrop: {
            pointId: string;
            position: [number, number, number];
            isCurved: boolean;
            handleA: [number, number, number] | null;
            handleB: [number, number, number] | null;
        }[],
        dropPickup: {
            pointId: string;
            position: [number, number, number];
            isCurved: boolean;
            handleA: [number, number, number] | null;
            handleB: [number, number, number] | null;
        }[],
    }
    triggers: TriggerSchema[];
}

interface RoboticArmAction {
    actionUuid: string;
    actionName: string;
    actionType: "pickAndPlace";
    process: { startPoint: [number, number, number] | null; endPoint: [number, number, number] | null; };
    triggers: TriggerSchema[];
}

interface MachineAction {
    actionUuid: string;
    actionName: string;
    actionType: "process";
    processTime: number;
    swapMaterial: string;
    triggers: TriggerSchema[];
}

interface StorageAction {
    actionUuid: string;
    actionName: string;
    actionType: "store" | "retrieve";
    materialType?: string;
    storageCapacity: number;
    triggers: TriggerSchema[];
}

interface HumanAction {
    actionUuid: string;
    actionName: string;
    actionType: "worker" | "assembly";
    processTime: number;
    swapMaterial?: string;
    assemblyPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; }
    pickUpPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; }
    dropPoint?: { position: [number, number, number] | null; rotation: [number, number, number] | null; }
    loadCount: number;
    loadCapacity: number;
    triggers: TriggerSchema[];
}

type Action = ConveyorAction | VehicleAction | RoboticArmAction | MachineAction | StorageAction | HumanAction;

// Points
interface ConveyorPointSchema {
    uuid: string;
    position: [number, number, number];
    rotation: [number, number, number];
    action: ConveyorAction;
}

interface VehiclePointSchema {
    uuid: string;
    position: [number, number, number];
    rotation: [number, number, number];
    action: VehicleAction;
}

interface RoboticArmPointSchema {
    uuid: string;
    position: [number, number, number];
    rotation: [number, number, number];
    actions: RoboticArmAction[];
}

interface MachinePointSchema {
    uuid: string;
    position: [number, number, number];
    rotation: [number, number, number];
    action: MachineAction;
}

interface StoragePointSchema {
    uuid: string;
    position: [number, number, number];
    rotation: [number, number, number];
    action: StorageAction;
}

interface HumanPointSchema {
    uuid: string;
    position: [number, number, number];
    rotation: [number, number, number];
    actions: HumanAction[];
}

type PointsScheme = | ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema | HumanPointSchema;

// Events
interface ConveyorEventSchema extends AssetEventSchema {
    type: "transfer";
    speed: number;
    points: ConveyorPointSchema[];
}

interface VehicleEventSchema extends AssetEventSchema {
    type: "vehicle";
    speed: number;
    point: VehiclePointSchema;
}

interface RoboticArmEventSchema extends AssetEventSchema {
    type: "roboticArm";
    speed: number;
    point: RoboticArmPointSchema;
}

interface MachineEventSchema extends AssetEventSchema {
    type: "machine";
    point: MachinePointSchema;
}

interface StorageEventSchema extends AssetEventSchema {
    type: "storageUnit";
    point: StoragePointSchema;
}

interface HumanEventSchema extends AssetEventSchema {
    type: "human";
    speed: number;
    point: HumanPointSchema;
}

type EventsSchema = | ConveyorEventSchema | VehicleEventSchema | RoboticArmEventSchema | MachineEventSchema | StorageEventSchema | HumanEventSchema;

// Statuses
interface ConveyorStatus extends ConveyorEventSchema {
    productUuid: string;
    isActive: boolean;
    isPaused: boolean;
    idleTime: number;
    activeTime: number;
}

interface MachineStatus extends MachineEventSchema {
    productUuid: string;
    isActive: boolean;
    idleTime: number;
    activeTime: number;
    currentAction?: {
        actionUuid: string;
        actionName: string;
        materialType: string | null;
        materialId: string | null;
    };
}

interface ArmBotStatus extends RoboticArmEventSchema {
    productUuid: string;
    isActive: boolean;
    idleTime: number;
    activeTime: number;
    currentAction?: {
        actionUuid: string;
        actionName: string;
        materialType: string | null;
        materialId: string | null;
    };
}

interface VehicleStatus extends VehicleEventSchema {
    productUuid: string;
    isActive: boolean;
    isPicking: boolean;
    idleTime: number;
    activeTime: number;
    currentLoad: number;
    currentMaterials: { materialType: string; materialId: string; }[];
    distanceTraveled: number;
}

interface StorageUnitStatus extends StorageEventSchema {
    productUuid: string;
    isActive: boolean;
    idleTime: number;
    activeTime: number;
    currentLoad: number;
    currentMaterials: { materialType: string; materialId: string; }[];
}

interface HumanStatus extends HumanEventSchema {
    productUuid: string;
    currentPhase: string;
    isActive: boolean;
    isScheduled: boolean;
    idleTime: number;
    activeTime: number;
    totalLoadCount: number;
    currentLoad: number;
    currentMaterials: { materialType: string; materialId: string; }[];
    distanceTraveled: number;
    currentAction?: {
        actionUuid: string;
        actionName: string;
    };
}

// Materials
interface MaterialSchema {
    materialId: string;
    materialName: string;
    materialType: string;
    isActive: boolean;
    isVisible: boolean;
    isPaused: boolean;
    isRendered: boolean;
    startTime?: number;
    endTime?: number;
    cost?: number;
    weight?: number;

    previous?: {
        modelUuid: string;
        pointUuid: string;
        actionUuid: string;
    };

    current: {
        modelUuid: string;
        pointUuid: string;
        actionUuid: string;
    };

    next?: {
        modelUuid: string;
        pointUuid: string;
    } | null;
}

type MaterialsSchema = MaterialSchema[];

// Products
type productsSchema = {
    productName: string;
    productUuid: string;
    eventDatas: EventsSchema[];
}[];

// Material History
interface MaterialHistoryEntry {
    material: MaterialSchema;
    removedAt: string;
}

type MaterialHistorySchema = MaterialHistoryEntry[];

//IK

type Link = {
    index: number;
    enabled: boolean;
    rotationMin?: [number, number, number];
    rotationMax?: [number, number, number];
    limitation?: [number, number, number];
};

type IK = {
    target: number;
    effector: number;
    links: Link[];
    minDistance?: number;
    maxDistance?: number;
    maxheight?: number;
    minheight?: number;
};
