<template>
  <q-card flat class="full-width q-pa-none">
    <q-card-section class="full-width">
      <div class="row items-center">
        <div class="col">
          <div class="text-h6">{{ t('CHD') }}</div>
        </div>
        <div class="col-auto">
          <q-btn flat :label="t('button.prev')" @click="emitPrev" class="q-mr-sm" />
          <q-btn color="primary" :label="t('button.next')" @click="saveAndNext" />
        </div>
      </div>
      <q-separator class="q-my-sm" />

      <q-form ref="formRef" class="q-gutter-md q-mt-md">
        <div class="row items-center">
          <div class="col">
            <q-toggle v-model="form.hasChildren" :label="t('children.hasChildren')" />
          </div>
          <div class="col-auto">
            <q-btn v-if="form.hasChildren" :disable="form.children.length >= 5" color="primary" :label="`+ ${t('children.addChild')}`" @click="openAddModal" />
          </div>
        </div>

        <div v-if="form.hasChildren" class="q-mt-md">
          <div class="text-subtitle2 q-mb-sm">{{ t('children.listTitle') }}</div>

          <q-list bordered>
            <q-item v-for="(child, i) in form.children" :key="i" clickable>
              <q-item-section>
                <q-item-label><span class="text-weight-bold">{{ child.firstName || '-' }} {{ child.lastName || '' }} ({{ ageFromDate(child.birthDate) }})</span></q-item-label>
                <q-item-label v-if="!modalDraft.sameHousehold">{{  formatAddressToString(child.address) }}</q-item-label>
              </q-item-section>
              <q-item-section side class="row items-center q-gutter-sm">
                <q-btn dense flat round icon="edit" @click="openEditModal(i)" />
                <q-btn dense flat round icon="delete" color="negative" @click="deleteChild(i)" />
              </q-item-section>
            </q-item>
          </q-list>
        </div>


        <div v-if="hasTriggeredOverLimit || form.children.length >= 5" class="q-mt-md">
          <q-input type="textarea" v-model="form.moreThanFiveChildrenNote" :label="t('children.moreThanFiveChildrenNote')" autogrow />
        </div>
      </q-form>

      <!-- Modal for adding/editing a child -->
      <q-dialog v-model="isDialogOpen" persistent>
        <q-card class="contained-card child-modal">
          <q-card-section>
            <div class="text-h6">{{ editingIndex === null ? t('children.addChild') : t('children.editChild') }}</div>
            <q-separator class="q-my-sm" />
            <q-form ref="modalFormRef" class="q-gutter-md q-mt-md">
              <q-input class="q-mt-none" dense v-model="modalDraft.firstName" :label="t('children.firstName')" :rules="modalFirstNameRules" @blur="onNameBlur('firstName')" />
              <q-input class="q-mt-none" dense v-model="modalDraft.lastName" :label="t('children.lastName')" :rules="modalLastNameRules" @blur="onNameBlur('lastName')">
                <template v-slot:prepend>
                  <q-btn
                    dense
                    flat
                    round
                    color="primary"
                    icon="family_restroom"
                    :disable="!taxpayerLastName"
                    @click.stop.prevent="copyLastNameFromTaxpayer"
                  >
                    <q-tooltip class="bg-primary text-white">{{ t('children.copyLastNameFromTaxpayer') }}</q-tooltip>
                  </q-btn>
                </template>
              </q-input>
              <q-input class="q-mt-none" dense v-model="modalDraft.birthDate" type="date" :label="t('children.birthDate')" :rules="modalBirthDateRules" />
              <div class="row items-center q-gutter-sm q-mt-none">
                <div class="col">
                  <q-toggle class="q-mt-none" v-model="modalDraft.sameHousehold" :label="t('children.sameHousehold')" />
                <div class="q-mt-none"  v-if="!modalDraft.sameHousehold">
                  <q-toggle class="q-mt-none" v-model="modalDraft.alimentiVersati" :label="t('children.alimentiVersati')" />
                </div>
                </div>

              </div>

              <div v-if="!modalDraft.sameHousehold" class="q-ml-lg q-mt-none">
                <div class="row items-center q-gutter-sm q-mb-xs">
                  <div class="col-auto">
                    <q-btn dense flat round icon="edit" @click="openAddressModal">
                      <q-tooltip class="bg-primary text-white">{{ t('children.editAddress') }}</q-tooltip>
                    </q-btn>
                  </div>
                  <div class="col">
                    <div class="text-caption">{{ t('children.addressLabel') }}</div>
                  </div>
                </div>
                <div class="q-pa-xs bg-grey-2 q-px-md">
                  <div v-if="!modalDraft.address" class="text-negative">{{ t('validation.insertAddress') }}</div>
                  <div v-else class="q-pa-xs">{{ formattedModalAddress }}</div>
                </div>

              </div>
              <q-input class="q-mt-none" dense v-model="modalDraft.school" :label="t('children.school')" />
              <div class="row">
              <q-toggle class="q-mt-none" v-model="modalDraft.hasCareCost" :label="t('children.hasCareCost')" />
              <CommentAttachment
                class="q-mt-none"
                v-if="modalDraft.hasCareCost"
                v-model="modalDraft.careCosts"
                :label="t('children.careCosts')"
                :id="'children'"
              />
              </div>
              </q-form>
          </q-card-section>
          <AddressModal v-model="isAddressDialogOpen" :modelAddress="modalAddressObject" :allowForeign="false" @save="onAddressSave" @cancel="onAddressCancel" />
          <q-card-actions align="right">
            <q-btn flat :label="t('button.cancel')" @click="closeModal" />
            <q-btn color="primary" :label="editingIndex === null ? t('button.add') : t('button.save')" @click="confirmModal" />
          </q-card-actions>
        </q-card>
      </q-dialog>
    </q-card-section>
  </q-card>
</template>

<script setup lang="ts">
import { reactive, onMounted, ref, nextTick, watch, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import AddressModal from '../AddressModal.vue'
import type { Address } from '../../types/address'
import { useChildrenStore, type ChildItem, type ChildrenData } from '../../stores/children'
import { useTaxstore } from '../../stores/taxstore'
import type { StepDescriptor } from '../../types/types'
import CommentAttachment from '../CommentAttachment.vue'

const props = defineProps<{ step?: StepDescriptor }>()
const emit = defineEmits(['next', 'prev'])

const { t } = useI18n()
const store = useChildrenStore()
const taxStore = useTaxstore()

const taxpayerLastName = computed(() => {
  const ln = taxStore.getTaxpayer()?.lastName
  return typeof ln === 'string' ? ln.trim() : ''
})

// QForm ref
const formRef = ref<{ validate?: () => Promise<boolean> | boolean; resetValidation?: () => void } | null>(null)

const requiredMessage = (fallback = 'Required') => {
  const msg = t('validation.required')
  return msg && msg !== 'validation.required' ? msg : fallback
}
const required = (msg?: string) => (v: unknown) => {
  const message = msg || requiredMessage()
  if (v === null || v === undefined) return message
  if (typeof v === 'string') return (v.trim() !== '') || message
  if (Array.isArray(v)) return v.length > 0 || message
  return true
}

const minLength = (n: number, msg?: string) => (v: unknown) => {
  const message = msg || `${t('validation.minLength') || `Minimum ${n} chars`}`
  if (v === null || v === undefined) return true
  if (typeof v === 'string') return (v.trim().length >= n) || message
  return true
}

const maxAgeFromJan1 = (years: number, msg?: string) => (v: unknown) => {
  const i18nMsg = t('validation.maxAgeFromJan1')
  const message = msg || (typeof i18nMsg === 'string' ? i18nMsg : `Age must be at most ${years} years from Jan 1 of this year`)
  if (!v) return true

  let d: Date
  if (v instanceof Date) {
    d = v
  } else if (typeof v === 'string') {
    d = new Date(v)
  } else {
    return message
  }

  if (isNaN(d.getTime())) return message
  const now = new Date()
  const cutoff = new Date(now.getFullYear() - years, 0, 1)
  return d >= cutoff || message
}

const formatAddressToString = (v?: Address | null) => {
  if (!v) return ''

  const country = v.country
  const countryCode = typeof country === 'object' && country !== null ? country.code : country
  const countryName = typeof country === 'object' && country !== null ? country.name : ''

  if (countryCode === 'CH') {
    return [v.street, String(v.zip || ''), v.city, v.canton || ''].filter(Boolean).join(', ')
  }
  return [v.street, String(v.zip || ''), v.city, countryName].filter(Boolean).join(', ')
}

function onNameBlur(field: 'firstName' | 'lastName') {
  const raw = (modalDraft[field] ?? '') as unknown
  const s = typeof raw === 'string' ? raw.trim() : String(raw)
  if (!s) {
    modalDraft[field] = ''
    return
  }
  modalDraft[field] = s.charAt(0).toUpperCase() + s.slice(1)
}

function copyLastNameFromTaxpayer() {
  const ln = taxpayerLastName.value
  if (!ln) return
  modalDraft.lastName = ln
}

function ageFromDate(d?: string) {
  if (!d) return ''
  const dt = new Date(d)
  if (isNaN(dt.getTime())) return ''
  const now = new Date()
  let age = now.getFullYear() - dt.getFullYear()
  const m = now.getMonth() - dt.getMonth()
  if (m < 0 || (m === 0 && now.getDate() < dt.getDate())) age--
  if (age < 0) return ''
  return `${age} anni`
}

const makeEmptyChild = (): ChildItem => ({
  firstName: '',
  lastName: '',
  birthDate: '',
  sameHousehold: true,
  school: '',
  hasCareCost: false,
  careCosts: { comments: '', attachments: [] },
  address: null,
  alimentiVersati: false
})

const form = reactive<ChildrenData>({
  hasChildren: false,
  children: [],
  moreThanFiveChildrenNote: ''
})

const hasTriggeredOverLimit = ref(false)

// childRequired intentionally removed; modal rules are used instead

// modal state
const isDialogOpen = ref(false)
const editingIndex = ref<number | null>(null)
const modalDraft = reactive<ChildItem>({ ...makeEmptyChild() })
const modalFormRef = ref<{ validate?: () => Promise<boolean> | boolean; resetValidation?: () => void } | null>(null)
const isAddressDialogOpen = ref(false)
const modalAddressObject = ref<Address | null>(null)

const formattedModalAddress = computed(() => {
  const a = modalAddressObject.value
  if (!a) return ''
  return formatAddressForString(a)
})
// over-limit modal removed; note edited inline
const modalFirstNameRules = [required(), minLength(2)]
const modalLastNameRules = [required(), minLength(2)]
const modalBirthDateRules = [required(), maxAgeFromJan1(25)]

async function openAddModal() {
  editingIndex.value = null
  Object.assign(modalDraft, makeEmptyChild())
  // clear any previously stored address object
  modalDraft.address = null
  isDialogOpen.value = true
  await nextTick()
  modalFormRef.value?.resetValidation?.()
}

async function openEditModal(index: number) {
  const c = form.children[index]
  if (!c) return

  editingIndex.value = index
  Object.assign(modalDraft, { ...makeEmptyChild(), ...c })
  // restore stored address object if present on the child
  modalDraft.address = c.address || null
  modalAddressObject.value = modalDraft.address || null
  isDialogOpen.value = true
  await nextTick()
  modalFormRef.value?.resetValidation?.()
}

function closeModal() {
  isDialogOpen.value = false
}

function openAddressModal() {
  // pass an Address prop to the AddressModal: prefer the stored object, otherwise
  // construct a minimal Address from the saved address string so the modal can render it
  if (modalDraft.address) {
    modalAddressObject.value = modalDraft.address
  } else {
    modalAddressObject.value = null
  }
  isAddressDialogOpen.value = true
}

function onAddressCancel() {
  isAddressDialogOpen.value = false
}

function formatAddressForString(a: Address) {
  function hasCountryName(x: unknown): x is { name: string } {
    return typeof x === 'object' && x !== null && Object.prototype.hasOwnProperty.call(x, 'name')
  }
  const countryLabel = a.country && typeof a.country === 'object' && hasCountryName(a.country) ? a.country.name : (a.country || '')
  // use tab-separated fields: street<TAB>zip<TAB>city<TAB>country
  return `${a.street || ''}\t${a.zip || ''}\t${a.city || ''}\t${countryLabel || ''}`
}

function onAddressSave(a: Address) {
  modalAddressObject.value = a
  // store object on the draft so it persists with the child entry
  modalDraft.address = a
  // do not persist the composed string; use formatted string only for rendering
  isAddressDialogOpen.value = false
}

async function confirmModal() {
  try {
    const ok = await (modalFormRef.value?.validate?.() ?? true)
    if (ok === false) return
  } catch {
    return
  }

  if (editingIndex.value === null) {
    // If already at or above limit, mark over-limit and abort
    if (form.children.length >= 5) {
      isDialogOpen.value = false
      hasTriggeredOverLimit.value = true
      return
    }

    // push new child
    form.children.push({ ...modalDraft })
    // persist immediately
    store.setChildren(buildPayload())

    // if we've just reached the maximum, mark over-limit
    if (form.children.length === 5) {
      isDialogOpen.value = false
      hasTriggeredOverLimit.value = true
      return
    }
  } else {
    form.children[editingIndex.value] = { ...modalDraft }
    // persist immediately
    store.setChildren(buildPayload())
  }

  isDialogOpen.value = false
}

function deleteChild(index: number) {
  form.children.splice(index, 1)
  store.setChildren(buildPayload())
}

// over-limit modal removed; note edited inline and persisted via watcher

onMounted(async () => {
  const saved = store.getChildren()
  if (saved) {
    form.hasChildren = !!saved.hasChildren
    if (Array.isArray(saved.children) && saved.children.length) {
      // copy up to 5
      for (let i = 0; i < 5; i++) {
        if (saved.children[i]) {
          form.children[i] = { ...form.children[i], ...(saved.children[i] as Partial<ChildItem>) } as ChildItem
        }
      }
    }
    form.moreThanFiveChildrenNote = saved.moreThanFiveChildrenNote || ''
    if (saved.moreThanFiveChildrenNote || (Array.isArray(saved.children) && saved.children.length >= 5)) {
      hasTriggeredOverLimit.value = true
    }
  }

  await nextTick()
  formRef.value?.resetValidation?.()
})

// persist when hasChildren toggles
watch(() => form.hasChildren, () => {
  store.setChildren(buildPayload())
})

// persist note immediately when edited
watch(() => form.moreThanFiveChildrenNote, () => {
  store.setChildren(buildPayload())
})

function buildPayload() {
  const payload = {
    hasChildren: form.hasChildren,
    children: form.children.filter(c => c.firstName || c.lastName || c.birthDate),
    moreThanFiveChildrenNote: form.moreThanFiveChildrenNote
  }
  // limit to 5 items
  payload.children = payload.children.slice(0, 5)
  return payload
}

async function saveAndNext() {
  try {
    const ok = await (formRef.value?.validate?.() ?? true)
    if (ok === false) return
  } catch {
    return
  }
  const payload = buildPayload()
  store.setChildren(payload)
  emit('next', props.step?.next)
}

function emitPrev() {
  const payload = buildPayload()
  store.setChildren(payload)
  emit('prev', props.step?.prev)
}

defineExpose({ buildPayload })
</script>

<style scoped>
.full-width { width: 100%; }
.contained-card { min-width: 480px; max-width: 720px; }
.contained-card .q-card-section { padding: 16px; }
.contained-card .q-card-actions { padding: 12px 16px; }
.child-modal { min-width: 480px; }
</style>
