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

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

const emit = defineEmits<{
  save: [payload: Record<string, any>]
  'update:modelValue': [value: boolean]
}>()

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

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

const fieldTypeOptions = Object.entries(FIELD_TYPE_LABELS).map(([value, title]) => ({ title, value }))

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

const defaultForm = () => ({
  label: '',
  field_type: 'text' as string,
  options: [] as string[],
  tag_category: null as string | null,
  is_required: false,
  is_filterable: false,
  is_portal_visible: true,
  is_admin_only: false,
  section: '',
  help_text: '',
})

const form = ref(defaultForm())

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

const showOptions = computed(() =>
  FIELD_TYPES_WITH_OPTIONS.includes(form.value.field_type as any),
)

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.options ? [...props.field.options] : [],
        tag_category: props.field.tag_category,
        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,
        section: props.field.section ?? '',
        help_text: props.field.help_text ?? '',
      }
    }
    else {
      form.value = defaultForm()
    }
  }
})

function addOption() {
  form.value.options.push('')
}

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

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

    errors.value = {}
    const payload: Record<string, any> = {
      label: form.value.label,
      is_required: form.value.is_required,
      is_filterable: form.value.is_filterable,
      is_portal_visible: form.value.is_portal_visible,
      is_admin_only: form.value.is_admin_only,
      section: form.value.section || null,
      help_text: form.value.help_text || null,
    }

    if (!props.field) {
      payload.field_type = form.value.field_type
    }

    if (showOptions.value) {
      payload.options = form.value.options.filter(o => o.trim() !== '')
    }
    else {
      payload.options = null
    }

    if (showTagCategory.value) {
      payload.tag_category = form.value.tag_category || null
    }
    else {
      payload.tag_category = null
    }

    emit('save', payload)
  })
}

function setErrors(err: any) {
  const data = err.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">
              <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">
              <AppSelect
                v-model="form.field_type"
                label="Type"
                :items="fieldTypeOptions"
                :rules="[requiredValidator]"
                :error-messages="errors.field_type"
                :disabled="!!field"
                :hint="field ? 'Type kan niet gewijzigd worden na aanmaken' : ''"
                :persistent-hint="!!field"
              />
            </VCol>

            <!-- Options (conditional) -->
            <VCol
              v-if="showOptions"
              cols="12"
            >
              <label class="text-body-2 mb-2 d-block">Opties</label>
              <div
                v-for="(_, index) in form.options"
                :key="index"
                class="d-flex align-center gap-x-2 mb-2"
              >
                <AppTextField
                  v-model="form.options[index]"
                  :placeholder="`Optie ${index + 1}`"
                  density="compact"
                  hide-details
                />
                <VBtn
                  icon="tabler-x"
                  variant="text"
                  size="small"
                  color="error"
                  @click="removeOption(index)"
                />
              </div>
              <VBtn
                variant="tonal"
                size="small"
                prepend-icon="tabler-plus"
                @click="addOption"
              >
                Optie toevoegen
              </VBtn>
              <p
                v-if="errors.options"
                class="text-error text-caption mt-1"
              >
                {{ errors.options }}
              </p>
            </VCol>

            <!-- Tag category (conditional) -->
            <VCol
              v-if="showTagCategory"
              cols="12"
            >
              <AppAutocomplete
                v-model="form.tag_category"
                label="Tag-categorie"
                :items="tagCategories ?? []"
                clearable
                :error-messages="errors.tag_category"
                placeholder="Alle tags (laat leeg voor alle categorieën)"
              />
            </VCol>

            <VCol
              cols="12"
              md="6"
            >
              <AppTextField
                v-model="form.section"
                label="Sectie"
                placeholder="bijv. Over jou"
                :error-messages="errors.section"
              />
            </VCol>
            <VCol
              cols="12"
              md="6"
            />
            <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>

            <!-- 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>
          </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>
