<script setup lang="ts">
import { reactive, ref, watch } from 'vue';
import { SRGBColorSpace } from 'three';
import { TresCanvas, } from '@tresjs/core';
import { useGLTF, OrbitControls } from '@tresjs/cientos';
import { useItem } from '../../stores/item';
import { useRawData } from '../../stores/raw_data';
import { IMAGE_URL } from '../../constants';

const raw_dataStore = useRawData()
const pageStore = useItem()

const camera = ref()
const controls = ref()
const models = ref([] as model3DType[])

const controlsState = reactive({
    enableDamping: true,
    maxPolarAngle: (Math.PI / 2) - 0.07,
    minAzimuthAngle: (Math.PI / 2) - 0.20,
    enablePan: false,
    enableZoom: false,
    autoRotate: true,
})

const loadModels = async () => {
    camera.value.minDistance = raw_dataStore.data.min_distance;
    camera.value.maxDistance = raw_dataStore.data.max_distance;
    const d = raw_dataStore.data.max_distance * 0.5;
    camera.value.position.set(d, d, d)
    for (let index = 0; index < raw_dataStore.data.elements.length; index++) {
        const element = raw_dataStore.data.elements[index];
        const item = {} as model3DType

        if (element.name == 'ground') continue

        item.modelUrl = `${IMAGE_URL}/${element.model_file}`
        let { scene: loaded_scene } = await useGLTF(item.modelUrl)
        item.modelFile = loaded_scene
        item.id = element.id
        item.name = element.name

        if (!element.is_enabled) {
            item.modelFile.visible = false
        }

        if (item.modelFile.children[0]) {
            item.modelFile.children[0].position.set(
                item.modelFile.children[0].position.x + element.x_pos,
                item.modelFile.children[0].position.y + element.y_pos,
                item.modelFile.children[0].position.z + element.z_pos
            )
            item.modelFile.children[0].updateMatrixWorld(true)
        }
        models.value.push(item)
    }
}

if (!raw_dataStore.data.id && pageStore.page.id) {
    await raw_dataStore.load({ source: pageStore.page.id })
    await loadModels();
    controls.value.autoRotate = true
    controls.value.value.update()
}

watch(() => pageStore.page.id, async () => {
    await raw_dataStore.load({ source: pageStore.page.id })
    await loadModels()
    controls.value.autoRotate = true
    controls.value.value.update()

})
</script>
<template>
    <div class="main">
        <h1 class="main-title">
            {{ raw_dataStore.data.name }}
        </h1>
        <div class="main-desc">
            <p v-for="p in (raw_dataStore.data.description || '').replace(/(\n|\r)+/g, '\n').split('\n')">
                {{ p }}
            </p>
        </div>
        <div class="main-canvas">
            <TresCanvas :output-encoding="SRGBColorSpace">
                <TresPerspectiveCamera ref="camera" />
                <OrbitControls v-bind="controlsState" make-default ref="controls" />
                <TresGroup ref="scene">
                    <template v-for="item in models">
                        <TresGroup :name="item.name">
                            <TresObject3D v-bind="item.modelFile.clone()" />
                        </TresGroup>
                    </template>
                </TresGroup>
            </TresCanvas>
        </div>
    </div>
</template>