import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { Bee } from './Bee.js';
import { Waypoint } from './Waypoint.js';

export class Hive {

    static collection = [];
    constructor(scene) {
        this.scene = scene;
        this.position = new THREE.Vector3();
        this.rotation = new THREE.Vector3();
        this.model = null;
        this.honeyReserve = 0;
        this.beeSlots = 10;
        this.queenSlots = 1;
        this.entranceWaypoint = null;
        this.billboard = null;
        this.yWobble = 0;
        this.swarm;
    }
    static loadModel() {
        return new Promise((resolve, reject) => {
            var gltfloader = new GLTFLoader();
            return gltfloader.load(
                './beehive/scene.gltf',
                function (gltf) {
                    resolve(gltf);
                },
                function (xhr) { },
                function (error) {
                    reject(error);
                }
            );
        });
    }
    async load(model) {
        this.model = model.scene.clone() ?? await Hive.loadModel().scene;
        this.billboardCanvas = document.createElement('canvas');
        this.billboardCanvas.width = 500;
        this.billboardCanvas.height = 300;
        this.billboardContext = this.billboardCanvas.getContext('2d');
        this.billboardTexture = new THREE.CanvasTexture(this.billboardCanvas);
        this.billboard = new THREE.Sprite(new THREE.SpriteMaterial({ map: this.billboardTexture }));
    }

    init(i) {
        this.model.scale.set(50, 50, 50);
        this.model.traverse(function (node) {
            if (node.isMesh) { node.castShadow = true; node.receiveShadow = true; }
        });
        this.position.x = (70 * i) - 70;
        this.position.z = Math.abs((20 * i) - 20);
        this.rotation.y = ((Math.PI / 4)) - ((Math.PI / 4) * i);
        this.entranceWaypoint = Waypoint.addNewHive(this.scene, this);
        this.billboard.position.set(this.position.x, this.position.y + 100, this.position.z);
        this.billboard.scale.set(this.billboardCanvas.width / 10, this.billboardCanvas.height / 10, 1);
    }

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

    update(delta, timer) {
        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);

        this.yWobble = Math.cos(timer * 0.008) * 4;

        this.billboardContext.clearRect(0, 0, this.billboardCanvas.width, this.billboardCanvas.height);
        this.canvasDraw(this.billboardContext);
        this.billboardTexture.needsUpdate = true;
    }

    canvasDraw(context) {
        context.fillStyle = "#EB9605";
        context.beginPath();
        context.moveTo(40, this.yWobble + 72);
        context.bezierCurveTo(40, this.yWobble + 72, 70, this.yWobble + 72, 40, this.yWobble + 20);
        context.bezierCurveTo(40, this.yWobble + 20, 10, this.yWobble + 72, 40, this.yWobble + 72);
        context.fill();


        context.beginPath();
        context.arc(40, this.yWobble + 124, 20, 0, 2 * Math.PI);
        context.fill();

        context.fillStyle = "white";
        context.font = "72px Arial";
        context.textAlign = "left";
        context.fillText(`Honey ${this.honeyReserve}`, 72, 72);

        context.fillStyle = "white";
        context.font = "72px Arial";
        context.textAlign = "left";
        context.fillText(`Bees ${10 - this.beeSlots}`, 72, 144);
    }

    visitFromBee(bee) {
        this.honeyReserve += bee.carryingHoney;
        bee.carryingHoney = 0;
        //let randomFlower = Flower.collection[Math.floor(Flower.collection.length * Math.random())];
        //bee.setTarget(randomFlower);
        bee.setTarget(this.entranceWaypoint);
        this.spawnBee();
    }

    spawnBee() {
        if (this.honeyReserve > 15 && this.beeSlots > 0) {
            this.honeyReserve -= 15;
            this.beeSlots--;
            let newBee = new Bee();
            newBee.model = Bee.baseModel.clone();
            newBee.model.material = newBee.model.material.clone();
            newBee.init();
            newBee.setSwarm(this.swarm);
            newBee.setHive(this);
            newBee.setPosition(this.position.x, this.position.y, this.position.z);
            newBee.setLastPosition(this.position.x, this.position.y, this.position.z);
            // newBee.setTarget(Flower.collection[0]);
            newBee.setTarget(this.entranceWaypoint);
            newBee.addToScene(this.scene);
            Bee.collection.push(newBee);
        }
        if (this.honeyReserve > 200 && this.queenSlots > 0) {
            this.honeyReserve -= 200;
            this.queenSlots--;
            let newBee = new Bee();
            newBee.model = Bee.baseModel.clone();
            newBee.model.material = newBee.model.material.clone();
            newBee.init();
            let claimedHives = Bee.collection.map(bee => bee.homeHive);
            let nextHive = Hive.collection.filter(hive => !claimedHives.includes(hive))[0];
            if (!nextHive) {
                return;
            }
            newBee.setSwarm(this.swarm);
            newBee.setHive(nextHive);
            newBee.setPosition(this.position.x, this.position.y, this.position.z);
            newBee.setLastPosition(nextHive.position.x, nextHive.position.y, nextHive.position.z);
            newBee.setTarget(nextHive);
            newBee.addToScene(this.scene);
            Bee.collection.push(newBee);
        }
    }

    toggleFlower(flower) {
        if (!this.entranceWaypoint.contains(flower)) {
            this.entranceWaypoint.addLink(flower);
            this.entranceWaypoint.addLine(flower);
        } else {
            this.entranceWaypoint.removeLink(flower);
            this.entranceWaypoint.removeLine(flower);
        }
    }

    setSwarm(id) {
        this.swarm = id;
    }
}
