<template>
    <MalioDrawer v-model="drawerOpen">
        <template #header>
            <h2 class="text-[32px] font-semibold text-primary-500">Imprimer les absences</h2>
        </template>
        <form class="space-y-4" @submit.prevent="handleSubmit">
            <MalioDate
                v-model="printForm.from"
                label="Date de début"
                required
                :clearable="false"
                :reserve-message-space="false"
                :error="showFromError ? 'La date de début est obligatoire.' : ''"
                group-class="w-full"
            />

            <MalioDate
                v-model="printForm.to"
                label="Date de fin"
                required
                :clearable="false"
                :reserve-message-space="false"
                :error="showToError ? 'La date de fin est obligatoire.' : ''"
                group-class="w-full"
            />

            <div class="space-y-2">
                <p class="text-md font-semibold text-neutral-700">
                    Sites <span class="text-red-600">*</span>
                </p>
                <div class="flex flex-wrap gap-4 rounded-md border border-neutral-300 px-3 py-2">
                    <div v-for="site in sites" :key="site.id" class="flex items-center gap-2">
                        <div :style="{ backgroundColor: site.color }" class="h-4 w-4 rounded"></div>
                        <label class="text-md" :for="`print-site-${site.id}`">{{ site.name }}</label>
                        <input
                            :id="`print-site-${site.id}`"
                            v-model="printForm.siteIds"
                            :value="site.id"
                            type="checkbox"
                            class="h-4 w-4"
                        />
                    </div>
                </div>
                <p v-if="showSitesError" class="text-sm text-red-600">
                    Sélectionne au moins un site.
                </p>
            </div>

            <div class="space-y-2">
                <p class="text-md font-semibold text-neutral-700">
                    Type de contrat <span class="text-red-600">*</span>
                </p>
                <div class="flex flex-wrap gap-4 rounded-md border border-neutral-300 px-3 py-2">
                    <div v-for="nature in contractNatures" :key="nature.value" class="flex items-center gap-2">
                        <label class="text-md" :for="`print-contract-nature-${nature.value}`">{{ nature.label }}</label>
                        <input
                            :id="`print-contract-nature-${nature.value}`"
                            v-model="printForm.contractNatures"
                            :value="nature.value"
                            type="checkbox"
                            class="h-4 w-4"
                        />
                    </div>
                </div>
                <p v-if="showContractNaturesError" class="text-sm text-red-600">
                    Sélectionne au moins un type de contrat.
                </p>
            </div>

            <div class="space-y-2">
                <p class="text-md font-semibold text-neutral-700">
                    Temps de travail <span class="text-red-600">*</span>
                </p>
                <div class="flex flex-wrap gap-4 rounded-md border border-neutral-300 px-3 py-2">
                    <div v-for="workContract in workContracts" :key="workContract.id" class="flex items-center gap-2">
                        <label class="text-md" :for="`print-work-contract-${workContract.id}`">{{ workContract.name }}</label>
                        <input
                            :id="`print-work-contract-${workContract.id}`"
                            v-model="printForm.workContractIds"
                            :value="workContract.id"
                            type="checkbox"
                            class="h-4 w-4"
                        />
                    </div>
                </div>
                <p v-if="showWorkContractsError" class="text-sm text-red-600">
                    Sélectionne au moins un temps de travail.
                </p>
            </div>

            <div class="flex justify-center pt-2">
                <MalioButton
                    label="Imprimer"
                    variant="primary"
                    :button-class="submitButtonClass"
                    @click="handleSubmit"
                />
            </div>
        </form>
    </MalioDrawer>
</template>

<script setup lang="ts">
import { computed, reactive, toRef, watch } from 'vue'

type SiteOption = {
    id: number
    name: string
    color: string
}

type ContractNatureOption = {
    value: 'CDI' | 'CDD' | 'INTERIM'
    label: string
}

type WorkContractOption = {
    id: number
    name: string
}

const props = defineProps<{
    modelValue: boolean
    sites: SiteOption[]
    contractNatures: ContractNatureOption[]
    workContracts: WorkContractOption[]
    printForm: {
        from: string
        to: string
        siteIds: number[]
        contractNatures: Array<'CDI' | 'CDD' | 'INTERIM'>
        workContractIds: number[]
    }
}>()

const emit = defineEmits<{
    (event: 'update:modelValue', value: boolean): void
    (event: 'submit'): void
    (event: 'cancel'): void
}>()

const drawerOpen = computed({
    get: () => props.modelValue,
    set: (value: boolean) => emit('update:modelValue', value)
})

const printForm = toRef(props, 'printForm')

const validationTouched = reactive({
    from: false,
    to: false,
    sites: false,
    contractNatures: false,
    workContracts: false
})

const isFromValid = computed(() => printForm.value.from.trim() !== '')
const isToValid = computed(() => printForm.value.to.trim() !== '')
const isSitesValid = computed(() => printForm.value.siteIds.length > 0)
const isContractNaturesValid = computed(() => {
    if (props.contractNatures.length === 0) return true
    return printForm.value.contractNatures.length > 0
})
const isWorkContractsValid = computed(() => {
    if (props.workContracts.length === 0) return true
    return printForm.value.workContractIds.length > 0
})
const isFormValid = computed(
    () =>
        isFromValid.value &&
        isToValid.value &&
        isSitesValid.value &&
        isContractNaturesValid.value &&
        isWorkContractsValid.value
)

const showFromError = computed(() => validationTouched.from && !isFromValid.value)
const showToError = computed(() => validationTouched.to && !isToValid.value)
const showSitesError = computed(() => validationTouched.sites && !isSitesValid.value)
const showContractNaturesError = computed(() => validationTouched.contractNatures && !isContractNaturesValid.value)
const showWorkContractsError = computed(() => validationTouched.workContracts && !isWorkContractsValid.value)

const submitButtonClass = computed(() => {
    if (!isFormValid.value) {
        return 'opacity-50 cursor-not-allowed'
    }
    return ''
})

const handleSubmit = () => {
    validationTouched.from = true
    validationTouched.to = true
    validationTouched.sites = true
    validationTouched.contractNatures = true
    validationTouched.workContracts = true
    if (!isFormValid.value) return
    emit('submit')
}

const handleCancel = () => {
    emit('cancel')
    emit('update:modelValue', false)
}

watch(
    () => props.modelValue,
    (isOpen) => {
        if (!isOpen) {
            validationTouched.from = false
            validationTouched.to = false
            validationTouched.sites = false
            validationTouched.contractNatures = false
            validationTouched.workContracts = false
        }
    }
)
</script>
