<template>
  <div class="h-full flex flex-col overflow-hidden">
    <div class="flex items-center justify-between pb-6">
      <h1 class="text-4xl font-bold text-primary-500">Types de statut</h1>
      <MalioButton
        label="Ajouter"
        icon-name="mdi:plus"
        icon-position="left"
        @click="openCreate"
      />
    </div>

    <div
      v-if="!isLoading && absenceTypes.length === 0"
      class="rounded-lg border border-neutral-200 bg-white p-6 text-md text-neutral-600"
    >
      Aucun type pour le moment.
    </div>

    <div v-else class="min-h-0 overflow-auto rounded-md bg-white">
      <div class="grid grid-cols-4 gap-4 border border-black bg-tertiary-500 px-6 py-3 text-[20px] font-semibold text-black rounded-t-md sticky top-0 z-10">
        <span>Code</span>
        <span>Libellé</span>
        <span>Couleur</span>
        <span>Compte en heures</span>
      </div>
      <div v-if="isLoading" class="px-6 py-4 text-md text-neutral-500">
        Chargement...
      </div>
      <div v-else class="border-x border-b border-primary-500 rounded-b-md">
        <div
          v-for="type in absenceTypes"
          :key="type.id"
          class="grid grid-cols-4 items-center gap-4 border-b border-primary-500 px-6 py-3 text-md font-bold text-primary-500 last:border-b-0 cursor-pointer hover:bg-tertiary-500"
          @click="openEdit(type)"
        >
          <span>{{ type.code }}</span>
          <span>{{ type.label }}</span>
          <div class="flex items-center gap-2">
            <span
              class="inline-block h-3 w-3 rounded-full"
              :style="{ backgroundColor: type.color }"
            />
            <span class="text-md uppercase text-neutral-500">{{ type.color }}</span>
          </div>
          <div>
            <span
              class="inline-flex rounded-md px-2 py-1 text-sm font-semibold"
              :class="type.countAsWorkedHours ? 'bg-emerald-100 text-emerald-700' : 'bg-neutral-100 text-neutral-700'"
            >
              {{ type.countAsWorkedHours ? 'Oui' : 'Non' }}
            </span>
          </div>
        </div>
      </div>
    </div>

    <MalioDrawer v-model="isDrawerOpen">
      <template #header>
        <h2 class="text-[32px] font-semibold text-primary-500">{{ drawerTitle }}</h2>
      </template>
      <form class="space-y-4" @submit.prevent="handleSubmit">
        <MalioInputText :reserve-message-space="false"
          v-model="form.code"
          label="Code *"
          group-class="mt-2"
          :max-length="10"
          :error="showCodeError ? 'Le code est obligatoire.' : ''"
        />
        <MalioInputText :reserve-message-space="false"
          v-model="form.label"
          label="Libellé *"
          group-class="mt-2"
          :error="showLabelError ? 'Le libellé est obligatoire.' : ''"
        />
        <div>
          <label class="text-md font-semibold text-neutral-700">
            Compté comme travaillé
          </label>
          <div class="mt-2 flex items-center gap-6">
            <MalioRadioButton
              v-model="form.countAsWorkedHours"
              name="countAsWorkedHours"
              :value="true"
              label="Oui"
              group-class="w-auto mt-0"
            />
            <MalioRadioButton
              v-model="form.countAsWorkedHours"
              name="countAsWorkedHours"
              :value="false"
              label="Non"
              group-class="w-auto mt-0"
            />
          </div>
        </div>
        <div>
          <label class="text-md font-semibold text-neutral-700" for="color">
            Couleur <span class="text-red-600">*</span>
          </label>
          <div class="mt-2 flex items-center gap-3">
            <input
              id="color"
              v-model="form.color"
              type="color"
              :class="colorFieldClass"
            />
            <span class="text-md font-semibold text-neutral-600">{{ form.color }}</span>
          </div>
          <p v-if="showColorError" class="mt-1 text-sm text-red-600">
            La couleur est obligatoire.
          </p>
        </div>
        <div v-if="editingType" class="grid grid-cols-2 gap-3 pt-2">
          <MalioButton
            label="Supprimer"
            variant="danger"
            button-class="w-full"
            @click="confirmDelete(editingType)"
          />
          <MalioButton
            type="submit"
            label="Modifier"
            button-class="w-full"
            :disabled="isSubmitting || !isFormValid"
          />
        </div>
        <div v-else class="flex justify-center pt-2">
          <MalioButton
            type="submit"
            label="Valider"
            button-class="w-[200px]"
            :disabled="isSubmitting || !isFormValid"
          />
        </div>
      </form>
    </MalioDrawer>
  </div>
</template>

<script setup lang="ts">
import type { AbsenceType } from '~/services/dto/absence-type'
import { createAbsenceType, deleteAbsenceType, listAbsenceTypes, updateAbsenceType } from '~/services/absence-types'

useHead({
    title: 'Types de statut'
})

const isDrawerOpen = ref(false)
const isSubmitting = ref(false)
const isLoading = ref(false)

const absenceTypes = ref<AbsenceType[]>([])
const editingType = ref<AbsenceType | null>(null)

const drawerTitle = computed(() =>
  editingType.value ? "Modifier un type" : "Ajouter un type"
)

const form = reactive({
  code: '',
  label: '',
  color: '#222783',
  countAsWorkedHours: true
})

const validationTouched = reactive({
  code: false,
  label: false,
  color: false
})

const isCodeValid = computed(() => form.code.trim() !== '')
const isLabelValid = computed(() => form.label.trim() !== '')
const isColorValid = computed(() => form.color.trim() !== '')
const isFormValid = computed(
  () => isCodeValid.value && isLabelValid.value && isColorValid.value
)

const showCodeError = computed(() => validationTouched.code && !isCodeValid.value)
const showLabelError = computed(() => validationTouched.label && !isLabelValid.value)
const showColorError = computed(() => validationTouched.color && !isColorValid.value)

const colorFieldClass = computed(() => {
  const baseColorClass = 'h-10 w-16 cursor-pointer rounded-md border bg-white p-1'
  if (showColorError.value) {
    return `${baseColorClass} border-red-500`
  }
  return `${baseColorClass} border-neutral-300`
})

const loadAbsenceTypes = async () => {
  isLoading.value = true
  try {
    absenceTypes.value = await listAbsenceTypes()
  } finally {
    isLoading.value = false
  }
}

onMounted(loadAbsenceTypes)

const resetForm = () => {
  form.code = ''
  form.label = ''
  form.color = '#222783'
  form.countAsWorkedHours = true
}

const openCreate = () => {
  editingType.value = null
  resetForm()
  isDrawerOpen.value = true
}

const openEdit = (type: AbsenceType) => {
  editingType.value = type
  form.code = type.code
  form.label = type.label
  form.color = type.color
  form.countAsWorkedHours = type.countAsWorkedHours
  isDrawerOpen.value = true
}

const closeDrawer = () => {
  isDrawerOpen.value = false
  editingType.value = null
  resetForm()
}

const handleSubmit = async () => {
  if (isSubmitting.value) return
  validationTouched.code = true
  validationTouched.label = true
  validationTouched.color = true
  if (!isFormValid.value) return

  isSubmitting.value = true
  try {
    if (editingType.value) {
      await updateAbsenceType(editingType.value.id, {
        code: form.code,
        label: form.label,
        color: form.color,
        countAsWorkedHours: form.countAsWorkedHours
      })
    } else {
      await createAbsenceType({
        code: form.code,
        label: form.label,
        color: form.color,
        countAsWorkedHours: form.countAsWorkedHours
      })
    }

    closeDrawer()
    await loadAbsenceTypes()
  } finally {
    isSubmitting.value = false
  }
}

watch(isDrawerOpen, (isOpen) => {
  if (!isOpen) {
    validationTouched.code = false
    validationTouched.label = false
    validationTouched.color = false
  }
})

const confirmDelete = async (type: AbsenceType) => {
  const ok = window.confirm(`Supprimer le type ${type.label} ?`)
  if (!ok) return

  await deleteAbsenceType(type.id)
  await loadAbsenceTypes()
}
</script>
