import * as THREE from 'three';
import { Hive } from '../js/Hive.js';

export class Bee {
    static collection = [];
    static baseModel = null;

    constructor() {
        this.position = new THREE.Vector3();
        this.rotation = new THREE.Vector3();
        this.lastPosition = new THREE.Vector3();
        this.targetPosition = new THREE.Vector3();
        this.maxSpeed = 0.5;
        this.model = null;
        this.homeHive = null;
        this.targetObject = null;
        this.carryingHoney = 0;
        this.swarm = 0;
    }
    static async loadGeo() {
        return new THREE.IcosahedronGeometry(3, 0);
    }
    static async loadMat() {
        return new THREE.MeshPhongMaterial({ color: 0xcccc00 });
    }

    static async loadModel() {
        return new THREE.Mesh(await Bee.loadGeo(), await Bee.loadMat());

    }
    async load(model) {
        this.model = model.clone() ?? await Bee.loadModel();
        this.init();
    }

    init() {
        this.model.castShadow = true;
        this.model.receiveShadow = true;
        this.targetPosition.x = 0;
        this.targetPosition.y = 15;
        this.targetPosition.z = 0;

        this.homeHive = Hive.collection[0];
    }

    addToScene(scene) {
        scene.add(this.model);
    }

    setHive(homeHive) {
        this.homeHive = homeHive;
    }

    setSwarm(id) {
        this.swarm = id;
        switch (this.swarm) {
            case 2:
                this.model.material.color.set(0xff0000);
                break;

            case 1:
            default:
                this.model.material.color.set(0xffff00);
                break;
        }
    }

    setPosition(x, y, z) {
        this.position.x = x;
        this.position.y = y;
        this.position.z = z;
    }

    setLastPosition(x, y, z) {
        this.lastPosition.x = x;
        this.lastPosition.y = y;
        this.lastPosition.z = z;
    }

    setTarget(target) {
        this.targetObject = target;
        this.setLastPosition(this.targetPosition.x, this.targetPosition.y, this.targetPosition.z);
        this.targetPosition.x = this.targetObject.position.x;
        this.targetPosition.y = this.targetObject.position.y;
        this.targetPosition.z = this.targetObject.position.z;
    }

    nextAction() {
        this.targetObject.visitFromBee(this);
    }

    update(delta, timer) {
        let fullDistance = Math.hypot(this.targetPosition.x - this.lastPosition.x, this.targetPosition.z - this.lastPosition.z);
        let distanceDone = Math.hypot(this.position.x - this.lastPosition.x, this.position.z - this.lastPosition.z);
        let radiansToTarget = Math.atan2(this.targetPosition.z - this.position.z, this.targetPosition.x - this.position.x);

        // why do these do weird things?
        // let fullDistance = this.targetPosition.distanceTo(this.lastPosition);
        // let distanceDone = this.position.distanceTo(this.lastPosition);
        // let radiansToTarget = this.position.angleTo(this.targetPosition);

        let progressRatio = distanceDone / fullDistance;
        if (progressRatio >= 0.99) {
            this.nextAction();
            return;
        }


        this.position.x += this.maxSpeed * Math.cos(radiansToTarget);
        this.position.y = Math.cos(timer * 0.008) * 1 + 15;
        this.position.z += this.maxSpeed * Math.sin(radiansToTarget);

        this.rotation.x = 0;
        this.rotation.y = Math.sin(timer * 0.0005);
        this.rotation.z = Math.sin(timer * 0.0005);

        this.model.position.set(this.position.x, this.position.y, this.position.z);
        this.model.rotation.set(this.rotation.x, this.rotation.y, this.rotation.z);
    }

}
