import * as THREE from 'three'
import gsap from 'gsap'
import { loadGltf } from './library/loadgltf.js'

import potionIconVertex from './shaders/potionicon/vertex.glsl'
import potionIconFragment from './shaders/potionicon/fragment.glsl'

export default class Shopper {
    constructor(game, meshPath, potionInfo, scale, position, rotation, updateFunction) {
        this.game = game
        this.meshPath = meshPath
        this.desiredPotion = potionInfo
        this.scale = scale
        this.position = position
        this.rotation = rotation
        this.updateFunction = updateFunction
        this.rejectCount = 0
        this.rejectionColors = [
            new THREE.Color("yellow"),
            new THREE.Color("orange"),
            new THREE.Color("crimson")
        ]
    }

    async init() {
        const reaperMesh = await loadGltf(this.game, this.meshPath)
        reaperMesh.scale.copy(this.scale)
        this.object3d = new THREE.Group()
        this.object3d.add(reaperMesh)
        this.object3d.position.set(-15, 0.1, 10)
        this.object3d.rotateOnAxis(THREE.Object3D.DEFAULT_UP, this.rotation)
        this.game.scene.add(this.object3d)

        const defaultPlane = new THREE.PlaneGeometry(1, 1)
        const speechBubbleTexture = this.game.textureLoader.load('./textures/speechbubble.png')
        const textBubbleMaterial = new THREE.MeshBasicMaterial({
            map: speechBubbleTexture,
            transparent: true,
            side: THREE.DoubleSide,
        })

        const potionIconTexture = this.game.textureLoader.load(this.desiredPotion.image)
        const potionIconUniforms = {
            uPotionIcon: { value: potionIconTexture }
        }
        const potionIcon = new THREE.Mesh(defaultPlane.clone(), new THREE.ShaderMaterial({
            uniforms: potionIconUniforms,
            vertexShader: potionIconVertex,
            fragmentShader: potionIconFragment,
            transparent: true,
        }))
        potionIcon.position.y = 0.085
        potionIcon.position.z = 0.05
        potionIcon.scale.set(0.5, 0.5, 0.5)

        this.requestBillboard = new THREE.Group()
        this.billboardSprite = new THREE.Mesh(defaultPlane.clone(), textBubbleMaterial)
        this.requestBillboard.add(this.billboardSprite)
        this.requestBillboard.add(potionIcon)

        this.requestBillboard.position.x = 0
        this.requestBillboard.position.y = 2.5
        this.requestBillboard.position.z = 0

        this.requestBillboard.visible = false

        this.object3d.add(this.requestBillboard)

        gsap.to(this.object3d.position, {duration: 2, x: this.position.x, y: this.position.y, z: this.position.z})
    }

    update(elapsedTime) {
        this.updateFunction(elapsedTime)
    }

    showDesire() {
        if (this.object3d.wantIsAnimating) {
            return
        }

        this.object3d.wantIsAnimating = true

        this.object3d.wantIsAnimating = true
        this.requestBillboard.lookAt(this.game.camera.position)
        this.requestBillboard.visible = true

        this.requestBillboard.position.set(0, 0.5, 0)
        this.requestBillboard.scale.set(0, 0, 0)

        gsap.to(this.requestBillboard.position, {
            duration: 2, y: 2.5, ease: "elastic", onUpdate: () => {
                this.requestBillboard.lookAt(this.game.camera.position)
            }
        })
        gsap.to(this.requestBillboard.scale, {
            duration: 2, x: 1, y: 1, z: 1, ease: "elastic", onComplete: () => {
                this.object3d.wantIsAnimating = false
            }
        })


    }

    hideDesire() {
        this.object3d.wantIsAnimating = true
        gsap.to(this.requestBillboard.position, { duration: 2, y: 0.5, ease: "back" })
        gsap.to(this.requestBillboard.scale, {
            duration: 2, x: 0, y: 0, z: 0, ease: "back", onComplete: () => {
                this.requestBillboard.visible = false
                this.object3d.wantIsAnimating = false
            }
        })
    }

    acceptPotion() {
        //give money
        //show happy billboard
    }

    rejectPotion(rejectAmount = 1) {
        this.rejectCount += rejectAmount
        
        this.billboardSprite.material.color = this.rejectionColors[Math.min(2, this.rejectCount - 1)]
    }

    showSad() {
        //show sad billboard
        console.log("not what I wanted")
    }

    isMatchingPotion(possiblePotionInfo) {
        return this.desiredPotion.name == possiblePotionInfo.name
    }
}