<script setup lang="ts">
import { BufferGeometry, Matrix4, Vector3 } from 'three';

const props = defineProps(['index', 'models'])

const lamelle_height = use_lamelle_height()
const lamelles_count = use_lamelles_count()
const fence_section = use_fence_section()
const section_count = use_section_count()
const extra_section = use_extra_section()
const remove_pillar = use_remove_pillar()
const max_size = use_max_size()

const lSize = lamelle_height.value
const bSize = 0.0235
const pillar_size = 104 * 0.001

const pillar_one_pos = ref(fence_section.value * -0.5 - 0.015)
const pillar_two_pos = ref(fence_section.value * 0.5 + pillar_size + bSize - 0.01)

const scale_koef = 2.5
const show_pillar_one = ref(props.index == 1)
const show_pillar_two = ref(true)

const last_element = ref(Math.min((section_count.value + ~~(!!extra_section.value)), max_size.value))
watch([section_count, fence_section, extra_section], () => {
    last_element.value = Math.min(section_count.value + ~~(!!extra_section.value), max_size.value)
})

const getExtraValue = () => (extra_section.value && props.index == last_element.value) ? extra_section.value * 0.001 : false
const extra = ref(getExtraValue())
if (extra.value) {
    pillar_one_pos.value = (extra.value as number) * -0.5 - 0.015
    pillar_two_pos.value = (extra.value as number) * 0.5 + pillar_size + bSize - 0.01
}

const make_translate_to_section = (source = fence_section.value) => {
    const one_s = (source + pillar_size + bSize) * scale_koef
    let r = (props.index - 1) * one_s
    if (typeof extra.value == 'number') {
        r -= (fence_section.value - extra.value) * scale_koef * 0.5
    }
    return r
}
const translate_to_section = ref(make_translate_to_section())
watch([fence_section, extra], () => {
    translate_to_section.value = make_translate_to_section()
})

const instanced_lamelle = shallowRef();
const instanced_lamelle_geometry = Object.assign(new BufferGeometry, props.models.lamelle.children[0].geometry)
const instanced_lamelle_material = props.models.lamelle.children[0].material
const instanced_lamelle_count = 24
const instanced_v = [instanced_lamelle_geometry, instanced_lamelle_material, instanced_lamelle_count]
watch([instanced_lamelle, fence_section, extra_section, lamelles_count, extra], () => {
    // console.log(props.index, instanced_v, instanced_lamelle.value)
    for (let i = 0; i < instanced_lamelle_count; i++) {
        if (instanced_lamelle.value) {
            const scale_x = (((extra.value as number) || fence_section.value) * 10)
            const pos_x = pillar_size * 0.5
            const pos_y = (lSize * i)
            const pos_z = 0.02
            const newmatrix = new Matrix4().fromArray([
                scale_x, 0, 0, 0,
                0, 1, 0, 0,
                0, 0, 1, 0,
                pos_x, pos_y, pos_z, 1
            ])
            instanced_lamelle.value.setMatrixAt(i, newmatrix);

            if (i >= lamelles_count.value) {
                instanced_lamelle.value.setMatrixAt(i, new Matrix4().makeTranslation(new Vector3(0, 20, 20)));
            }
        }
        instanced_lamelle.value.instanceMatrix.needsUpdate = true
    }
});

watch([section_count, fence_section, extra_section], () => {
    extra.value = getExtraValue()
    if (extra_section.value && props.index == last_element.value) {
        pillar_one_pos.value = (extra.value as number) * -0.5 - 0.015
        pillar_two_pos.value = (extra.value as number) * 0.5 + pillar_size + bSize - 0.01
        // translate_to_section.value = make_translate_to_section(extra_section.value * 0.001)
    } else {
        pillar_one_pos.value = fence_section.value * -0.5 - 0.015
        pillar_two_pos.value = fence_section.value * 0.5 + pillar_size + bSize - 0.01
        // translate_to_section.value = make_translate_to_section()
    }
})
</script>
<template>
    <TresGroup :scale="scale_koef" :position-x="translate_to_section" :name="`fence ${index}`" :position-y="0">
        <TresGroup name="pillar_one" v-if="!remove_pillar && show_pillar_one" :position-x="pillar_one_pos"
            :position-z="0">
            <TresGroup :position-y="(lSize * -0.5)" :scale="[1, 0.5, 1]">
                <TresObject3D v-bind="props.models.fence.children[0]" />
            </TresGroup>
            <TresObject3D v-bind="props.models.fence.children[0]" :scale-y="lamelles_count" />
            <TresGroup :position-y="(lSize * lamelles_count)" :scale="[1, 0.5, 1]">
                <TresObject3D v-bind="props.models.fence.children[0]" />
            </TresGroup>
        </TresGroup>

        <TresGroup name="pillar_two" v-if="!remove_pillar && show_pillar_two" :position-x="pillar_two_pos"
            :position-z="0">
            <TresGroup :position-y="(lSize * -0.5)" :scale="[-1, 0.5, 1]">
                <TresObject3D v-bind="props.models.fence.children[0]" />
            </TresGroup>
            <TresObject3D v-bind="props.models.fence.children[0]" :scale="[-1, lamelles_count, 1]" />
            <TresGroup :position-y="(lSize * lamelles_count)" :scale="[-1, 0.5, 1]">
                <TresObject3D v-bind="props.models.fence.children[0]" />
            </TresGroup>
        </TresGroup>

        <TresGroup name="lamelles">
            <TresInstancedMesh ref="instanced_lamelle" :args="instanced_v" cast-shadow />
        </TresGroup>
        <TresGroup name="lam_fastening_one" :position-x="pillar_one_pos" :scale-y="lamelles_count">
            <TresObject3D v-bind="props.models.fastening.children[0]" />
        </TresGroup>
        <TresGroup name="lam_fastening_two" :position-x="pillar_two_pos" :scale="[-1, lamelles_count, 1]">
            <TresObject3D v-bind="props.models.fastening.children[0]" />
        </TresGroup>
        <TresGroup name="top_section" :scale-x="((extra as number) || fence_section) * 10 + 0.1 * scale_koef"
            :position="[pillar_size * 0.5, lamelles_count * lSize, 0]">
            <TresObject3D v-bind="props.models.top.children[0]" />
        </TresGroup>
    </TresGroup>
</template>