<script setup lang="ts">
import type { FileUploadUploadEvent } from '~/node_modules/primevue/fileupload/FileUpload.d.ts'
import PF from 'pathfinding'

interface SvgContext {
    array: number[][],
    paths: string[],
    width: number,
    height: number
}
const config = useRuntimeConfig()
const plan: Ref<SvgContext | {}> = useState('plan', () => ({}));

const loading = ref<boolean>(false)
const canvasElement: Ref<HTMLCanvasElement | undefined> = ref();
const context: Ref<CanvasRenderingContext2D | undefined> = ref();

const canvasElement2: Ref<HTMLCanvasElement | undefined> = ref();
const context2: Ref<CanvasRenderingContext2D | undefined> = ref();

const grid = ref<number[][]>()
const startPoint = ref<number[]>()
const endPoint = ref<number[]>()
const startToEndPath = ref()

const beforeUpload = () => {
    loading.value = true
}

const onUpload = (event: FileUploadUploadEvent) => {
    loading.value = false
    try {
        const data = JSON.parse(event.xhr.response)
        plan.value = data.response
        startPoint.value = undefined
        endPoint.value = undefined

        context.value = canvasElement.value?.getContext('2d') || undefined;
        if (canvasElement.value && context.value) {
            context.value.clearRect(0, 0, canvasElement.value.width, canvasElement.value.height);
            if (!plan.value.hasOwnProperty('paths')) return
            (plan.value).paths.forEach((path: string) => {
                if (!context.value) return
                context.value.fillStyle = 'rgba(255, 0, 255, 0.25)'
                context.value.fill(new Path2D(path));

                context.value.strokeStyle = 'blue'
                context.value.stroke(new Path2D(path));
            });
        }

        context2.value = canvasElement2.value?.getContext('2d') || undefined;
        if (canvasElement2.value && context2.value) {
            plan.value.array.forEach((line, indexY) => {
                line.forEach((point, indexX) => {
                    context2.value.fillStyle = point > 0 ? 'red' : 'WHITE'
                    context2.value.fillRect(indexX, indexY, 1, 1)
                })
            });
        }

        grid.value = new PF.Grid(plan.value.array.map(y => y.map(x => x > 0 ? 1 : 0)))
    } catch (error) {
        console.error(error)
    }
}

const setPoint = (event: MouseEvent) => {
    try {

        const bound = event.currentTarget.getBoundingClientRect()

        const targetX = event.x - bound.x
        const targetY = event.y - bound.y

        if (!startPoint.value) {
            startPoint.value = [targetX, targetY]
            context2.value.fillStyle = 'rgb(0,255,0,0.75)';
            context2.value.beginPath();
            context2.value.arc(targetX, targetY, 10, 0, 2 * Math.PI);
            context2.value.fill();
        } else
            if (!endPoint.value) {
                endPoint.value = [targetX, targetY]
                context2.value.fillStyle = 'rgb(0,0,255,0.75)';
                context2.value.beginPath();
                context2.value.arc(targetX, targetY, 10, 0, 2 * Math.PI);
                context2.value.fill();

                const finder = new PF.AStarFinder();

                startToEndPath.value = finder.findPath(parseInt(startPoint.value[0]), parseInt(startPoint.value[1]), parseInt(endPoint.value[0]), parseInt(endPoint.value[1]), grid.value);
                startToEndPath.value.forEach(element => {
                    context2.value.fillRect(element[0], element[1], 1, 1)
                });
            }
    } catch (error) {
        console.error(err)
    }
}
</script>
<template>
    <div class="flex flex-col gap-4">
        <Panel header="Загрузка файла">
            <FileUpload mode="basic" name="demo" :url="`${config.public.apiBase}/api/prepare_image`" accept="image/*"
                :maxFileSize="10000000" @upload="onUpload" @before-upload="beforeUpload" :auto="true"
                chooseLabel="Выберите файл" :disabled="loading" />
        </Panel>
        <Panel v-if="plan && (<any>plan).paths" header="Отрисовка из массива значений">
            <canvas ref="canvasElement2" :width="1200" height="400" @click="setPoint"></canvas>
        </Panel>
        <Panel v-if="plan && (<any>plan).paths" header="Парсинг изображения">
            <canvas ref="canvasElement" :width="1200" height="400"></canvas>
        </Panel>
    </div>
</template>