<template>
    <form ref="formRef" :class="{ submitted }" @submit.prevent="validate">
        <div class="grid grid-cols-2 h-[461px] items-start gap-y-8 gap-x-40 mb-16">
            <h1 class="font-bold text-5xl uppercase col-start-1 row-start-1 text-primary-500">Expédition</h1>
            <UiSelect
                id="shipment-user"
                v-model="form.userId"
                label="Nom de l'utilisateur"
                :options="users.map((user) => ({
                    value: String(user.id),
                    label: user.username
                }))"
                :loading="isLoadingUsers"
                wrapper-class="col-start-1 row-start-2"
                required
            />
            <UiDateInput
                id="shipment-date"
                v-model="form.shipmentDate"
                label="Date du jour"
                wrapper-class="col-start-1 row-start-3"
                required
            />
            <div class="col-start-1 row-start-4 h-[64px]">
                <div class="flex w-full items-end gap-[104px]">
                    <UiRadioGroup
                        id="shipment-type"
                        name="shipment-type"
                        label="Type d'expédition bovine"
                        input-class="accent-primary-700 focus:ring-primary-700"
                        wrapper-class=""
                        group-class="flex flex-row gap-[104px] w-[160px_160px] h-[32px]"
                        v-model="selectedShipmentTypeId"
                        :options="bovineShipment.map((type) => ({
                            value: String(type.id),
                            label: type.label
                        }))"
                        required
                    />
                    <UiNumberInput
                        id="shipment-type-quantity"
                        v-model="shipmentQuantity"
                        :placeholder="0"
                        :min="0"
                        :max="1200"
                        :disabled="!selectedShipmentTypeId"
                    />
                </div>
            </div>
            <UiSelect
                id="shipment-customer"
                v-model="form.customerId"
                label="Client"
                :options="customers.map((customer) => ({
                    value: String(customer.id),
                    label: customer.name || `Client #${customer.id}`
                }))"
                :loading="isLoadingCustomers"
                wrapper-class="col-start-1 row-start-5"
                required
            />
            <UiSelect
                id="shipment-address"
                v-model="form.addressId"
                :options="addressOptions"
                :disabled="isLoadingCustomers || ownerAddresses.length === 0"
                label="Adresse"
                wrapper-class="col-start-2 row-start-1"
                required
            />
            <UiSelect
                id="shipment-truck"
                v-model="form.truckId"
                label="Camion"
                :options="trucks.map((truck) => ({
                    value: String(truck.id),
                    label: truck.name
                }))"
                :loading="isLoadingTrucks"
                wrapper-class="col-start-2 row-start-2"
                required
            />
            <UiSelect
                id="shipment-carrier"
                v-model="form.carrierId"
                label="Transporteur"
                :options="carriers.map((carrier) => ({
                    value: String(carrier.id),
                    label: carrier.name
                }))"
                wrapper-class="col-start-2 row-start-3"
                required
            />
            <div v-if="!isLiotCarrier" class="col-start-2 row-start-4">
                <UiLicensePlateInput
                    v-model="form.licensePlate"
                    v-model:allowAny="allowAnyLicensePlate"
                    required
                />
            </div>
            <UiSelect
                v-if="isLiotCarrier"
                id="shipment-vehicle"
                v-model="form.vehicleId"
                label="Immatriculation"
                :options="filteredVehicles.map((vehicle) => ({
                    value: String(vehicle.id),
                    label: vehicle.plate
                }))"
                :loading="isLoadingVehicles"
                :disabled="isLoadingVehicles || filteredVehicles.length === 0"
                wrapper-class="col-start-2 row-start-4"
                required
            />
            <UiSelect
                id="shipment-driver"
                v-model="form.driverId"
                label="Nom du chauffeur si LIOT"
                :options="filteredDrivers.map((driver) => ({
                    value: String(driver.id),
                    label: driver.name
                }))"
                :loading="isLoadingDrivers"
                wrapper-class="col-start-2 row-start-5"
                v-if="isLiotCarrier"
                required
            />
        </div>
        <div class="flex justify-center">
            <UiButton
                type="submit"
                class="text-xl mb-16 uppercase bg-primary-500 text-white h-[50px] w-[272px] justify-self-end"
                @click="submitted = true"
            >Valider
            </UiButton>
        </div>
    </form>
</template>

<script setup lang="ts">
import { useFormDataLoading } from '~/composables/useFormDataLoading'
import { useLiotHandling } from '~/composables/useLiotHandling'
import { useAddressSync } from '~/composables/useAddressSync'
import type { CustomerData } from '~/services/dto/customer-data'
import { getCustomerList } from '~/services/customer'
import type { ShipmentFormData } from '~/services/dto/shipment-data'
import { useShipmentStore } from '~/stores/shipment'
import type { ShipmentTypeData } from '~/services/dto/shipment-type-data'
import { getShipmentTypeList } from '~/services/shipment-type'

const router = useRouter()
const shipmentStore = useShipmentStore()
const isHydrating = ref(false)
const submitted = ref(false)
const formRef = ref<HTMLFormElement | null>(null)

const form = reactive<ShipmentFormData>({
    userId: '',
    shipmentDate: new Date().toISOString().slice(0, 10),
    customerId: '',
    addressId: '',
    truckId: '',
    carrierId: '',
    driverId: '',
    vehicleId: '',
    licensePlate: '',
})

const customers = ref<CustomerData[]>([])
const isLoadingCustomers = ref(false)
const bovineShipment = ref<ShipmentTypeData[]>([])
const selectedShipmentTypeId = ref('')
const shipmentQuantity = ref<number | null>(0)

const { users, trucks, carriers, isLoadingUsers, isLoadingTrucks, isLoadingCarriers, loadCommonData } =
    useFormDataLoading(form)

const {
    isLiotCarrier, filteredDrivers, filteredVehicles,
    isLoadingDrivers, isLoadingVehicles, allowAnyLicensePlate,
    loadDrivers, loadVehicles
} = useLiotHandling(form, carriers, isHydrating)

const customerIdRef = computed(() => form.customerId)
const { ownerAddresses, addressOptions } = useAddressSync(form, customerIdRef, customers)

const loadCustomers = async () => {
    isLoadingCustomers.value = true
    try {
        customers.value = await getCustomerList()
    } finally {
        isLoadingCustomers.value = false
    }
}

watch(
    () => shipmentStore.current,
    (shipment) => {
        isHydrating.value = true
        form.licensePlate = shipment?.licensePlate ?? ''
        form.shipmentDate = shipment?.shipmentDate?.slice(0, 10) ?? new Date().toISOString().slice(0, 10)
        form.userId = shipment?.user?.id ? String(shipment.user.id) : form.userId
        form.customerId = shipment?.customer?.id ? String(shipment.customer.id) : ''
        form.addressId = shipment?.address?.id ? String(shipment.address.id) : ''
        form.truckId = shipment?.truck?.id ? String(shipment.truck.id) : ''
        form.carrierId = shipment?.carrier?.id ? String(shipment.carrier.id) : ''
        form.driverId = shipment?.driver?.id ? String(shipment.driver.id) : ''
        form.vehicleId = shipment?.vehicle?.id ? String(shipment.vehicle.id) : ''
        selectedShipmentTypeId.value = shipment?.shipmentType?.id ? String(shipment.shipmentType.id) : ''
        shipmentQuantity.value = shipment?.nbBovinSend ?? 0
        isHydrating.value = false
    },
    { immediate: true }
)

// Extra watcher for LIOT defaults after hydration
watch(
    () => isHydrating.value,
    (value) => {
        if (!value && isLiotCarrier.value) {
            if (filteredDrivers.value.length === 1 && !form.driverId) {
                form.driverId = String(filteredDrivers.value[0].id)
            }
            if (filteredVehicles.value.length === 1 && !form.vehicleId) {
                form.vehicleId = String(filteredVehicles.value[0].id)
            }
        }
    }
)

onMounted(async () => {
    bovineShipment.value = await getShipmentTypeList()
    await loadCustomers()
    await loadCommonData()
    await loadVehicles()
    await loadDrivers()
})

const buildPayload = () => {
    const normalizedLicensePlate = form.licensePlate.trim()
    const normalizedShipmentDate = form.shipmentDate.trim()
    const normalizedCustomerId = form.customerId.trim()
    const normalizedTruckId = form.truckId.trim()
    const normalizedCarrierId = form.carrierId.trim()
    const normalizedDriverId = form.driverId.trim()
    const normalizedUserId = form.userId.trim()
    const normalizedAddressId = form.addressId.trim()

    const customerIri = normalizedCustomerId ? `/api/customers/${normalizedCustomerId}` : null
    const truckIri = normalizedTruckId ? `/api/trucks/${normalizedTruckId}` : null
    const carrierIri = normalizedCarrierId ? `/api/carriers/${normalizedCarrierId}` : null
    const userIri = normalizedUserId ? `/api/users/${normalizedUserId}` : null
    const driverIri = normalizedDriverId ? `/api/drivers/${normalizedDriverId}` : null
    const addressIri = normalizedAddressId ? `/api/addresses/${normalizedAddressId}` : null
    const normalizedShipmentTypeId = selectedShipmentTypeId.value.trim()
    const shipmentTypeIri = normalizedShipmentTypeId ? `/api/shipment_types/${normalizedShipmentTypeId}` : null

    const rawQuantity = Number(shipmentQuantity.value ?? 0)
    const normalizedQuantity = Number.isFinite(rawQuantity) ? Math.max(0, Math.trunc(rawQuantity)) : 0

    return {
        licensePlate: normalizedLicensePlate,
        shipmentDate: normalizedShipmentDate,
        customer: customerIri,
        truck: truckIri,
        carrier: carrierIri,
        driver: driverIri,
        user: userIri,
        address: addressIri,
        shipmentType: shipmentTypeIri,
        nbBovinSend: normalizedQuantity,
    }
}

const saveDraft = async () => {
    const payload = buildPayload()
    if (!shipmentStore.current) {
        await shipmentStore.createShipment({
            currentStep: 0,
            ...payload
        })
        return
    }
    await shipmentStore.updateShipment(shipmentStore.current.id, {
        currentStep: shipmentStore.current.currentStep,
        ...payload
    })
}

const validateFields = () => {
    submitted.value = true
    return formRef.value?.reportValidity() ?? false
}

defineExpose({ saveDraft, validateFields })

const validate = async () => {
    const payload = buildPayload()
    if (!shipmentStore.current) {
        const created = await shipmentStore.createShipment({
            currentStep: 1,
            ...payload
        })
        if (created) {
            await shipmentStore.loadShipment(created.id)
            await router.push(`/shipment/${created.id}`)
        }
        return
    }
    const nextStep = shipmentStore.current.currentStep + 1
    await shipmentStore.updateShipment(shipmentStore.current.id, {
        currentStep: nextStep,
        ...payload
    })
    await shipmentStore.loadShipment(shipmentStore.current.id)
}
</script>
