<template>
    <form>
        <div class="grid grid-cols-3 gap-x-40 gap-y-8 mb-8">
            <UiNumberInput
                :key="weight.type"
                :label="'POIDS'"
                labelClass="font-bold uppercase text-xl "
                v-model="weight.weight"
                :disabled="!auth.isAdmin"
                :min="0"
                :max="48000"
            />

            <UiDateInput
                label="Date pesée"
                v-model="sharedWeightMeta.weighedAt"
                :disabled="!auth.isAdmin"
            />

            <UiNumberInput
                label="Dsd"
                class="col-start-2"
                labelClass="font-bold uppercase"
                v-model="sharedWeightMeta.dsd"
                :disabled="!auth.isAdmin"
            />
        </div>
    </form>
</template>

<script setup lang="ts">
import type {ReceptionFormWeight} from '~/services/dto/reception-data'
import {getReception} from '~/services/reception'
import {updateWeight} from "~/services/weight";
import {useAuthStore} from "~/stores/auth";
import {ref, watch} from "vue";

const props = defineProps<{
    idReception: number
    weightType: string
    isValidate: boolean
}>()

const idReception = props.idReception
const weightType = props.weightType

const auth = useAuthStore()

const form = reactive({
    weights: [
        {id: 0, type: 'tare' as const, weight: 0, dsd: null, weighedAt: null},
        {id: 0, type: 'gross' as const, weight: 0, dsd: null, weighedAt: null}
    ]
})

const weight = form.weights.find(w => w.type === weightType)
const initialWeight = ref<{ weight: number | null; dsd: number | null; weighedAt: string | null } | null>(null)

// DSD et date de pesée sont partagés entre tare et gross dans l'UI.
const sharedWeightMeta = reactive<{
    dsd: number | string | null
    weighedAt: string | null
}>({
    dsd: null,
    weighedAt: null
})

const normalizeMeta = () => {
    const sharedDsd =
        sharedWeightMeta.dsd === null || sharedWeightMeta.dsd === undefined || sharedWeightMeta.dsd === ''
            ? null
            : Number(sharedWeightMeta.dsd)
    const sharedWeighedAt =
        sharedWeightMeta.weighedAt === null || sharedWeightMeta.weighedAt === undefined || sharedWeightMeta.weighedAt === ''
            ? null
            : sharedWeightMeta.weighedAt

    return {
        dsd: Number.isFinite(sharedDsd) ? sharedDsd : null,
        weighedAt: sharedWeighedAt
    }
}

const hydrateFromReception = (reception: ReceptionFormWeight) => {
    // On hydrate chaque ligne par son type (tare/gross), sans dépendre d'un index.
    for (const receptionWeight of reception.weights) {
        const formWeight = form.weights.find(weight => weight.type === receptionWeight.type)
        if (formWeight) {
            Object.assign(formWeight, receptionWeight)
        }
    }

    // On récupère une valeur existante pour préremplir les champs partagés.
    const weightWithMeta = reception.weights.find(weight =>
        (weight.dsd !== null && weight.dsd !== undefined)
        || (weight.weighedAt !== null && weight.weighedAt !== undefined && weight.weighedAt !== '')
    )

    if (weightWithMeta) {
        sharedWeightMeta.dsd = weightWithMeta.dsd ?? null
        sharedWeightMeta.weighedAt = weightWithMeta.weighedAt ?? null
    }

    if (weight) {
        const normalized = normalizeMeta()
        initialWeight.value = {
            weight: weight.weight ?? null,
            dsd: normalized.dsd,
            weighedAt: normalized.weighedAt
        }
    }
}

onMounted(async () => {
    const reception = await getReception(idReception)
    hydrateFromReception(reception)
})

watch(
    () => props.isValidate,
    async (val) => {
        if (!val) return
        await runValidate()
    }
)

const hasChanged = (current: { weight: number | null; dsd: number | null; weighedAt: string | null }) => {
    if (!initialWeight.value) {
        return true
    }
    return (
        (current.weight ?? null) !== (initialWeight.value.weight ?? null) ||
        (current.dsd ?? null) !== (initialWeight.value.dsd ?? null) ||
        (current.weighedAt ?? null) !== (initialWeight.value.weighedAt ?? null)
    )
}

const runValidate = async () => {
    if (!weight?.id) {
        return
    }

    const normalized = normalizeMeta()
    const current = {
        weight: weight.weight ?? null,
        dsd: normalized.dsd,
        weighedAt: normalized.weighedAt
    }

    if (!hasChanged(current)) {
        return
    }

    await updateWeight(weight.id, {
        weight: current.weight,
        dsd: current.dsd,
        weighedAt: current.weighedAt
    })

    initialWeight.value = current
}

</script>
