<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>
      <button
        type="button"
        class="rounded-lg bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500"
        @click="openCreate"
      >
        + Ajouter un type
      </button>
    </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>

    <AppDrawer v-model="isDrawerOpen" :title="drawerTitle">
      <form class="space-y-4" @submit.prevent="handleSubmit">
        <div>
          <label class="text-md font-semibold text-neutral-700" for="code">
            Code <span class="text-red-600">*</span>
          </label>
          <input
            id="code"
            v-model="form.code"
            type="text"
            maxlength="10"
            :class="codeFieldClass"
          />
          <p v-if="showCodeError" class="mt-1 text-sm text-red-600">
            Le code est obligatoire.
          </p>
        </div>
        <div>
          <label class="text-md font-semibold text-neutral-700" for="label">
            Libellé <span class="text-red-600">*</span>
          </label>
          <input
            id="label"
            v-model="form.label"
            type="text"
            :class="labelFieldClass"
          />
          <p v-if="showLabelError" class="mt-1 text-sm text-red-600">
            Le libellé est obligatoire.
          </p>
        </div>
        <div>
          <label class="text-md font-semibold text-neutral-700">
            Compté comme travaillé
          </label>
          <div class="mt-2 flex items-center gap-6">
            <label class="inline-flex items-center gap-2 text-md text-neutral-800">
              <input
                v-model="form.countAsWorkedHours"
                type="radio"
                class="h-4 w-4"
                :value="true"
              />
              Oui
            </label>
            <label class="inline-flex items-center gap-2 text-md text-neutral-800">
              <input
                v-model="form.countAsWorkedHours"
                type="radio"
                class="h-4 w-4"
                :value="false"
              />
              Non
            </label>
          </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">
          <button
            type="button"
            class="flex items-center justify-center rounded-md bg-red-500 px-4 py-2 text-md font-semibold text-white hover:bg-red-600"
            @click="confirmDelete(editingType)"
          >
            Supprimer
          </button>
          <button
            type="submit"
            class="flex items-center justify-center rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500"
            :class="submitButtonClass"
          >
            Modifier
          </button>
        </div>
        <div v-else class="flex justify-center pt-2">
          <button
            type="submit"
            class="flex w-[200px] items-center justify-center gap-2 rounded-md bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500"
            :class="submitButtonClass"
          >
            + Ajouter
          </button>
        </div>
      </form>
    </AppDrawer>
  </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 baseInputClass =
  'mt-2 w-full rounded-md border px-3 py-2 text-base text-neutral-900 focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-secondary-500/20'
const codeFieldClass = computed(() => {
  if (showCodeError.value) {
    return `${baseInputClass} border-red-500`
  }
  return `${baseInputClass} border-neutral-300`
})
const labelFieldClass = computed(() => {
  if (showLabelError.value) {
    return `${baseInputClass} border-red-500`
  }
  return `${baseInputClass} border-neutral-300`
})
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 submitButtonClass = computed(() => {
  if (isSubmitting.value || !isFormValid.value) {
    return 'opacity-50 cursor-not-allowed'
  }
  return ''
})

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>
