<script setup lang="ts">
import { VForm } from 'vuetify/components/VForm'
import type { AxiosError } from 'axios'
import { usePersonTagCategories } from '@/composables/api/usePersonTags'
import { requiredValidator } from '@core/utils/validators'
import type { RegistrationFormField, RegistrationFormFieldCreateDTO } from '@/types/registration-form-field'
import type { FieldDisplayWidth, RegistrationFieldType } from '@/types/registration-field-template'
import { FIELD_TYPES_WITH_OPTIONS } from '@/types/registration-field-template'
import type { ApiErrorResponse } from '@/types/auth'

const props = defineProps<{
  orgId: string
  field?: RegistrationFormField | null
  isSaving: boolean
}>()

const emit = defineEmits<{
  save: [payload: Partial<RegistrationFormFieldCreateDTO>]
  'update:modelValue': [value: boolean]
}>()

const modelValue = defineModel<boolean>({ default: false })

const orgIdRef = computed(() => props.orgId)
const { data: tagCategories } = usePersonTagCategories(orgIdRef)

const fieldTypeItems = [
  { type: 'subheader', title: 'Structuur' },
  { title: 'Kop / Sectie-titel', value: 'heading', props: { prependIcon: 'tabler-heading' } },
  { type: 'divider' },
  { type: 'subheader', title: 'Invoervelden' },
  { title: 'Tekstveld', value: 'text', props: { prependIcon: 'tabler-letter-t' } },
  { title: 'Tekstvak (groot)', value: 'textarea', props: { prependIcon: 'tabler-text-size' } },
  { title: 'Getal', value: 'number', props: { prependIcon: 'tabler-hash' } },
  { title: 'Toggle (ja/nee)', value: 'boolean', props: { prependIcon: 'tabler-toggle-left' } },
  { title: 'Dropdown', value: 'select', props: { prependIcon: 'tabler-list' } },
  { title: 'Meervoudige keuze', value: 'multiselect', props: { prependIcon: 'tabler-checklist' } },
  { title: 'Keuzerondjes', value: 'radio', props: { prependIcon: 'tabler-circle-dot' } },
  { title: 'Checkbox', value: 'checkbox', props: { prependIcon: 'tabler-checkbox' } },
  { title: 'Tags & Vaardigheden', value: 'tag_picker', props: { prependIcon: 'tabler-tags' } },
]

const errors = ref<Record<string, string>>({})
const refVForm = ref<VForm>()

interface OptionEntry {
  label: string
  description: string
}

const defaultForm = () => ({
  label: '',
  field_type: 'text' as string,
  options: [] as OptionEntry[],
  tag_categories: [] as string[],
  is_required: false,
  is_filterable: false,
  is_portal_visible: true,
  is_admin_only: false,
  help_text: '',
  display_width: 'full' as FieldDisplayWidth,
})

const form = ref(defaultForm())

const dialogTitle = computed(() =>
  props.field ? 'Veld bewerken' : 'Nieuw veld',
)

const isHeading = computed(() => form.value.field_type === 'heading')

const showOptions = computed(() =>
  (FIELD_TYPES_WITH_OPTIONS as readonly string[]).includes(form.value.field_type),
)

const showTagCategory = computed(() => form.value.field_type === 'tag_picker')

watch(modelValue, open => {
  if (open) {
    errors.value = {}
    if (props.field) {
      form.value = {
        label: props.field.label,
        field_type: props.field.field_type,
        options: props.field.normalized_options
          ? props.field.normalized_options.map(o => ({ label: o.label, description: o.description ?? '' }))
          : [],
        tag_categories: props.field.tag_categories ?? [],
        is_required: props.field.is_required,
        is_filterable: props.field.is_filterable,
        is_portal_visible: props.field.is_portal_visible,
        is_admin_only: props.field.is_admin_only,
        help_text: props.field.help_text ?? '',
        display_width: props.field.display_width ?? 'full',
      }
    }
    else {
      form.value = defaultForm()
    }
  }
})

function addOption() {
  form.value.options.push({ label: '', description: '' })
}

function removeOption(index: number) {
  form.value.options.splice(index, 1)
}

function onSubmit() {
  refVForm.value?.validate().then(({ valid }) => {
    if (!valid)
      return

    errors.value = {}

    const payload: Partial<RegistrationFormFieldCreateDTO> = {
      label: form.value.label,
      help_text: form.value.help_text || null,
      display_width: form.value.display_width,
    }

    if (!props.field)
      payload.field_type = form.value.field_type as RegistrationFieldType

    if (!isHeading.value) {
      payload.is_required = form.value.is_required
      payload.is_filterable = form.value.is_filterable
      payload.is_portal_visible = form.value.is_portal_visible
      payload.is_admin_only = form.value.is_admin_only

      if (showOptions.value) {
        payload.options = form.value.options
          .filter(o => o.label.trim() !== '')
          .map(o => o.description.trim()
            ? { label: o.label, description: o.description }
            : { label: o.label },
          )
      }
      else {
        payload.options = null
      }

      if (showTagCategory.value)
        payload.tag_categories = form.value.tag_categories.length > 0 ? form.value.tag_categories : null

      else
        payload.tag_categories = null
    }

    emit('save', payload)
  })
}

function setErrors(err: Error) {
  const data = (err as AxiosError<ApiErrorResponse>).response?.data
  if (data?.errors) {
    errors.value = Object.fromEntries(
      Object.entries(data.errors).map(([k, v]) => [k, (v as string[])[0]]),
    )
  }
  else if (data?.message) {
    errors.value = { label: data.message }
  }
}

defineExpose({ setErrors })
</script>

<template>
  <VDialog
    v-model="modelValue"
    max-width="650"
  >
    <VCard :title="dialogTitle">
      <VForm
        ref="refVForm"
        @submit.prevent="onSubmit"
      >
        <VCardText>
          <VRow>
            <VCol cols="12">
              <AppSelect
                v-model="form.field_type"
                label="Type"
                :items="fieldTypeItems"
                :rules="[requiredValidator]"
                :error-messages="errors.field_type"
                :disabled="!!field"
                :hint="field ? 'Type kan niet gewijzigd worden na aanmaken' : ''"
                :persistent-hint="!!field"
              />
            </VCol>

            <!-- HEADING fields: simplified UI -->
            <template v-if="isHeading">
              <VCol cols="12">
                <AppTextField
                  v-model="form.label"
                  label="Kop tekst"
                  placeholder="bijv. Persoonlijke gegevens"
                  :rules="[requiredValidator]"
                  :error-messages="errors.label"
                  autofocus
                  autocomplete="one-time-code"
                />
              </VCol>
              <VCol cols="12">
                <AppTextField
                  v-model="form.help_text"
                  label="Omschrijving (optioneel)"
                  placeholder="Korte toelichting onder de kop"
                  :error-messages="errors.help_text"
                  hint="Verschijnt in kleinere tekst onder de kop"
                  persistent-hint
                />
              </VCol>
              <VCol cols="12">
                <VAlert
                  type="info"
                  variant="tonal"
                  density="compact"
                  icon="tabler-info-circle"
                >
                  Een kop groepeert de velden hieronder visueel. Het verzamelt geen antwoorden.
                </VAlert>
              </VCol>
            </template>

            <!-- Regular input fields: full UI -->
            <template v-else>
              <VCol cols="12">
                <AppTextField
                  v-model="form.label"
                  label="Label"
                  placeholder="Hoe heet dit veld?"
                  :rules="[requiredValidator]"
                  :error-messages="errors.label"
                  autofocus
                  autocomplete="one-time-code"
                />
              </VCol>

              <VCol cols="12">
                <AppTextarea
                  v-model="form.help_text"
                  label="Helptekst"
                  placeholder="Toelichting die onder het veld wordt getoond"
                  :error-messages="errors.help_text"
                  rows="2"
                />
              </VCol>

              <VCol cols="12">
                <AppSelect
                  v-model="form.display_width"
                  :items="[
                    { title: 'Volledige breedte', value: 'full' },
                    { title: 'Halve breedte', value: 'half' },
                  ]"
                  label="Veldbreedte"
                  :hint="form.display_width === 'half' ? 'Wordt naast een ander half-breed veld geplaatst' : ''"
                  persistent-hint
                />
              </VCol>

              <!-- Toggles -->
              <VCol cols="12">
                <div class="d-flex flex-wrap gap-x-6 gap-y-2">
                  <VSwitch
                    v-model="form.is_required"
                    label="Verplicht"
                    hide-details
                    density="compact"
                  />
                  <VSwitch
                    v-model="form.is_filterable"
                    label="Filterbaar bij inplannen"
                    hide-details
                    density="compact"
                  />
                  <VSwitch
                    v-model="form.is_portal_visible"
                    label="Zichtbaar voor deelnemer"
                    hide-details
                    density="compact"
                  />
                  <VSwitch
                    v-model="form.is_admin_only"
                    label="Alleen voor organisator"
                    hide-details
                    density="compact"
                  />
                </div>
              </VCol>

              <!-- Options section at bottom with visual separation -->
              <template v-if="showOptions">
                <VCol cols="12">
                  <VDivider class="mb-1" />
                </VCol>
                <VCol cols="12">
                  <div class="d-flex align-center justify-space-between mb-3">
                    <div>
                      <div class="text-subtitle-2">
                        Opties
                      </div>
                      <div class="text-caption text-medium-emphasis">
                        Waaruit kan de deelnemer kiezen?
                      </div>
                    </div>
                    <VBtn
                      variant="tonal"
                      size="small"
                      prepend-icon="tabler-plus"
                      @click="addOption"
                    >
                      Optie toevoegen
                    </VBtn>
                  </div>

                  <div
                    v-for="(option, index) in form.options"
                    :key="index"
                    class="mb-2"
                  >
                    <div class="d-flex align-center gap-2">
                      <VIcon
                        icon="tabler-grip-vertical"
                        size="16"
                        class="text-medium-emphasis flex-shrink-0"
                        style="cursor: grab;"
                      />
                      <AppTextField
                        v-model="option.label"
                        placeholder="Optie"
                        density="compact"
                        hide-details
                        class="flex-grow-1"
                        style="max-inline-size: 200px;"
                      />
                      <AppTextField
                        v-model="option.description"
                        placeholder="Beschrijving (optioneel)"
                        density="compact"
                        hide-details
                        class="flex-grow-1"
                      />
                      <VBtn
                        icon="tabler-trash"
                        variant="text"
                        color="error"
                        size="x-small"
                        class="flex-shrink-0"
                        @click="removeOption(index)"
                      />
                    </div>
                  </div>

                  <div
                    v-if="form.options.length === 0"
                    class="text-center text-medium-emphasis py-4"
                  >
                    Nog geen opties. Klik op "Optie toevoegen" om te beginnen.
                  </div>

                  <p
                    v-if="errors.options"
                    class="text-error text-caption mt-1"
                  >
                    {{ errors.options }}
                  </p>
                </VCol>
              </template>

              <!-- Tag categories (conditional) -->
              <template v-if="showTagCategory">
                <VCol cols="12">
                  <VDivider class="mb-1" />
                </VCol>
                <VCol cols="12">
                  <div class="text-subtitle-2 mb-1">
                    Tag-categorieën
                  </div>
                  <div class="text-caption text-medium-emphasis mb-3">
                    Kies één of meerdere categorieën. De deelnemer ziet alle tags uit deze categorieën.
                  </div>
                  <AppAutocomplete
                    v-model="form.tag_categories"
                    label="Categorieën"
                    :items="tagCategories ?? []"
                    multiple
                    chips
                    closable-chips
                    clearable
                    :error-messages="errors.tag_categories"
                    placeholder="Alle tags (laat leeg voor alle categorieën)"
                  />
                </VCol>
              </template>
            </template>
          </VRow>
        </VCardText>
        <VCardActions>
          <VSpacer />
          <VBtn
            variant="text"
            @click="modelValue = false"
          >
            Annuleren
          </VBtn>
          <VBtn
            type="submit"
            color="primary"
            :loading="isSaving"
          >
            Opslaan
          </VBtn>
        </VCardActions>
      </VForm>
    </VCard>
  </VDialog>
</template>
