<script setup lang="ts">
import type { RegistrationField } from '@/types/registration'

defineProps<{
  groups: { section: string | null; fields: RegistrationField[] }[]
  fieldErrors: Record<string, string>
}>()

const fieldValues = defineModel<Record<string, unknown>>('fieldValues', { required: true })

function hint(field: RegistrationField): string | undefined {
  return field.help_text ?? undefined
}

function ensureArray(slug: string): string[] {
  const v = fieldValues.value[slug]
  if (Array.isArray(v)) return v.map(String)
  fieldValues.value[slug] = []

  return fieldValues.value[slug] as string[]
}

function toggleCheckboxOption(slug: string, option: string, checked: boolean | null) {
  const arr = ensureArray(slug)
  const on = Boolean(checked)
  if (on) {
    if (!arr.includes(option)) arr.push(option)
  }
  else {
    const i = arr.indexOf(option)
    if (i !== -1) arr.splice(i, 1)
  }
  fieldValues.value[slug] = [...arr]
}

function isCheckboxOptionChecked(slug: string, option: string): boolean {
  const arr = fieldValues.value[slug]
  if (!Array.isArray(arr)) return false

  return arr.includes(option)
}

function numberModel(slug: string): string {
  const v = fieldValues.value[slug]
  if (v === null || v === undefined) return ''
  if (typeof v === 'number' && Number.isNaN(v)) return ''

  return String(v)
}

function onNumberInput(slug: string, raw: string) {
  if (raw === '' || raw === '-') {
    fieldValues.value[slug] = null

    return
  }
  const n = Number(raw)
  fieldValues.value[slug] = Number.isFinite(n) ? n : null
}
</script>

<template>
  <div v-if="groups.length === 0">
    <p class="text-body-2 text-medium-emphasis mb-0">
      Er zijn geen extra vragen voor dit evenement.
    </p>
  </div>

  <div
    v-for="(group, gi) in groups"
    :key="gi"
    class="mb-6"
  >
    <div class="dynamic-section-heading text-subtitle-2 font-weight-medium text-medium-emphasis pb-2 mb-4">
      {{ group.section?.trim() ? group.section : 'Algemeen' }}
    </div>

    <VRow>
      <VCol
        v-for="field in group.fields"
        :key="field.id"
        cols="12"
        :md="field.field_type === 'boolean' ? '12' : field.field_type === 'textarea' ? '12' : '6'"
      >
        <div :id="`dyn-field-${field.slug}`">
          <!-- text -->
          <VTextField
            v-if="field.field_type === 'text'"
            v-model="fieldValues[field.slug] as string"
            variant="outlined"
            density="comfortable"
            hide-details="auto"
            :label="field.label + (field.is_required ? ' *' : '')"
            :hint="hint(field)"
            persistent-hint
            :error-messages="fieldErrors[field.slug]"
            :class="{ 'dynamic-field-error': !!fieldErrors[field.slug] }"
          />

          <!-- number -->
          <VTextField
            v-else-if="field.field_type === 'number'"
            :model-value="numberModel(field.slug)"
            variant="outlined"
            type="number"
            density="comfortable"
            hide-details="auto"
            :label="field.label + (field.is_required ? ' *' : '')"
            :hint="hint(field)"
            persistent-hint
            :error-messages="fieldErrors[field.slug]"
            :class="{ 'dynamic-field-error': !!fieldErrors[field.slug] }"
            @update:model-value="(v: string | number | null) => onNumberInput(field.slug, String(v ?? ''))"
          />

          <!-- textarea -->
          <VTextarea
            v-else-if="field.field_type === 'textarea'"
            v-model="fieldValues[field.slug] as string"
            variant="outlined"
            rows="3"
            auto-grow
            density="comfortable"
            hide-details="auto"
            :label="field.label + (field.is_required ? ' *' : '')"
            :hint="hint(field)"
            persistent-hint
            :error-messages="fieldErrors[field.slug]"
            :class="{ 'dynamic-field-error': !!fieldErrors[field.slug] }"
          />

          <!-- select -->
          <VSelect
            v-else-if="field.field_type === 'select'"
            v-model="fieldValues[field.slug] as string"
            variant="outlined"
            density="comfortable"
            hide-details="auto"
            :items="field.options ?? []"
            :label="field.label + (field.is_required ? ' *' : '')"
            :hint="hint(field)"
            persistent-hint
            :error-messages="fieldErrors[field.slug]"
            :clearable="!field.is_required"
            :class="{ 'dynamic-field-error': !!fieldErrors[field.slug] }"
          />

          <!-- multiselect -->
          <VSelect
            v-else-if="field.field_type === 'multiselect'"
            v-model="fieldValues[field.slug] as string[]"
            variant="outlined"
            density="comfortable"
            hide-details="auto"
            multiple
            chips
            closable-chips
            :items="field.options ?? []"
            :label="field.label + (field.is_required ? ' *' : '')"
            :hint="hint(field)"
            persistent-hint
            :error-messages="fieldErrors[field.slug]"
            :class="{ 'dynamic-field-error': !!fieldErrors[field.slug] }"
          />

          <!-- checkbox (one per option) -->
          <div
            v-else-if="field.field_type === 'checkbox'"
            class="rounded-lg pa-4 border border-opacity-100"
            style="border-color: rgba(var(--v-border-color), var(--v-border-opacity));"
            :class="{ 'dynamic-field-error': !!fieldErrors[field.slug] }"
          >
            <div class="text-body-2 font-weight-medium mb-2">
              {{ field.label }}<span v-if="field.is_required" class="text-error"> *</span>
            </div>
            <p
              v-if="hint(field)"
              class="text-caption text-medium-emphasis mb-3"
            >
              {{ hint(field) }}
            </p>
            <div class="d-flex flex-column ga-1">
              <VCheckbox
                v-for="opt in (field.options ?? [])"
                :key="opt"
                :model-value="isCheckboxOptionChecked(field.slug, opt)"
                density="comfortable"
                hide-details
                :label="opt"
                @update:model-value="(v: boolean | null) => toggleCheckboxOption(field.slug, opt, v)"
              />
            </div>
            <div
              v-if="fieldErrors[field.slug]"
              class="text-caption text-error mt-2"
            >
              {{ fieldErrors[field.slug] }}
            </div>
          </div>

          <!-- radio -->
          <div v-else-if="field.field_type === 'radio'">
            <div class="text-body-2 font-weight-medium mb-1">
              {{ field.label }}<span v-if="field.is_required" class="text-error"> *</span>
            </div>
            <p
              v-if="hint(field)"
              class="text-caption text-medium-emphasis mb-2"
            >
              {{ hint(field) }}
            </p>
            <VRadioGroup
              v-model="fieldValues[field.slug] as string"
              density="comfortable"
              hide-details="auto"
              :error-messages="fieldErrors[field.slug]"
              :class="{ 'dynamic-field-error': !!fieldErrors[field.slug] }"
            >
              <VRadio
                v-for="opt in (field.options ?? [])"
                :key="opt"
                :label="opt"
                :value="opt"
                density="comfortable"
                hide-details
              />
            </VRadioGroup>
          </div>

          <!-- boolean -->
          <VSwitch
            v-else-if="field.field_type === 'boolean'"
            v-model="fieldValues[field.slug] as boolean"
            inset
            color="primary"
            density="comfortable"
            hide-details="auto"
            :label="field.label + (field.is_required ? ' *' : '')"
            :hint="hint(field)"
            persistent-hint
            :error-messages="fieldErrors[field.slug]"
            :class="{ 'dynamic-field-error': !!fieldErrors[field.slug] }"
          />

          <!-- tag_picker -->
          <VAutocomplete
            v-else-if="field.field_type === 'tag_picker'"
            v-model="fieldValues[field.slug] as string[]"
            variant="outlined"
            density="comfortable"
            hide-details="auto"
            multiple
            chips
            closable-chips
            :items="field.available_tags ?? []"
            item-title="name"
            item-value="id"
            :label="field.label + (field.is_required ? ' *' : '')"
            :hint="hint(field)"
            persistent-hint
            :error-messages="fieldErrors[field.slug]"
            :class="{ 'dynamic-field-error': !!fieldErrors[field.slug] }"
          />
        </div>
      </VCol>
    </VRow>
  </div>
</template>

<style scoped>
.dynamic-section-heading {
  border-block-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
}
</style>
