import type { Contact } from '~/modules/directory/services/dto/contact'
import type { Address } from '~/modules/directory/services/dto/address'
import { useContactService } from '~/modules/directory/services/contacts'
import { useAddressService } from '~/modules/directory/services/addresses'

type Owner = { client?: string, prospect?: string, prestataire?: string }

/**
 * Logique partagée des fiches détail Client/Prospect : blocs répétables Contact
 * et Adresse (chargement, ajout, suppression). L'édition est tenue en mémoire
 * localement ; la persistance se fait au clic sur « Enregistrer » (saveContacts/
 * saveAddresses), comme les formulaires de tâche — pas d'enregistrement au blur.
 * Paramétré par l'IRI du propriétaire (`{ client }` ou `{ prospect }`), réutilisé
 * tel quel par les deux pages.
 */
export function useDirectoryDetail(owner: Owner) {
    const { t } = useI18n()
    const contactService = useContactService()
    const addressService = useAddressService()

    const contacts = ref<Contact[]>([])
    const addresses = ref<Address[]>([])
    const savingContacts = ref(false)
    const savingAddresses = ref(false)

    function emptyContact(): Contact {
        return { id: 0, firstName: null, lastName: null, jobTitle: null, email: null, phonePrimary: null, phoneSecondary: null, ...owner }
    }
    function emptyAddress(): Address {
        return { id: 0, label: null, street: null, streetComplement: null, postalCode: null, city: null, country: 'FR', ...owner }
    }

    // Édition locale uniquement : on remplace le bloc en mémoire, rien n'est
    // persisté tant que l'utilisateur n'a pas cliqué sur « Enregistrer ».
    function onContactInput(index: number, value: Contact): void {
        contacts.value[index] = value
    }
    function onAddressInput(index: number, value: Address): void {
        addresses.value[index] = value
    }

    function addContact(): void {
        contacts.value.push(emptyContact())
    }
    function addAddress(): void {
        addresses.value.push(emptyAddress())
    }

    // Suppression immédiate (comme la corbeille du formulaire de tâche) : un bloc
    // déjà enregistré est supprimé côté serveur, une amorce non enregistrée est
    // simplement retirée de la liste.
    async function removeContact(index: number): Promise<void> {
        const c = contacts.value[index]
        if (c?.id && c.id > 0) await contactService.remove(c.id)
        contacts.value.splice(index, 1)
    }
    async function removeAddress(index: number): Promise<void> {
        const a = addresses.value[index]
        if (a?.id && a.id > 0) await addressService.remove(a.id)
        addresses.value.splice(index, 1)
    }

    // Confirmation de suppression d'un bloc (contact / adresse) : la corbeille du
    // bloc ouvre une modal ; la suppression effective n'a lieu qu'à la confirmation.
    const removeModalOpen = ref(false)
    const pendingRemoval = ref<{ type: 'contact' | 'address', index: number } | null>(null)

    const removeModalTitle = computed(() =>
        pendingRemoval.value?.type === 'address'
            ? t('directory.addresses.deleteConfirmTitle')
            : t('directory.contacts.deleteConfirmTitle'),
    )
    const removeModalMessage = computed(() =>
        pendingRemoval.value?.type === 'address'
            ? t('directory.addresses.deleteConfirmMessage')
            : t('directory.contacts.deleteConfirmMessage'),
    )

    function askRemoveContact(index: number): void {
        pendingRemoval.value = { type: 'contact', index }
        removeModalOpen.value = true
    }
    function askRemoveAddress(index: number): void {
        pendingRemoval.value = { type: 'address', index }
        removeModalOpen.value = true
    }
    async function confirmRemove(): Promise<void> {
        const p = pendingRemoval.value
        if (!p) return
        if (p.type === 'contact') await removeContact(p.index)
        else await removeAddress(p.index)
        removeModalOpen.value = false
        pendingRemoval.value = null
    }

    // Persistance au clic : met à jour les blocs existants, crée les nouveaux
    // blocs renseignés. Les amorces vides (sans contenu) sont ignorées.
    async function saveContacts(): Promise<void> {
        if (savingContacts.value) return
        savingContacts.value = true
        try {
            for (let i = 0; i < contacts.value.length; i++) {
                const c = contacts.value[i]
                if (!c) continue
                const payload = { firstName: c.firstName, lastName: c.lastName, jobTitle: c.jobTitle, email: c.email, phonePrimary: c.phonePrimary, phoneSecondary: c.phoneSecondary, ...owner }
                if (c.id && c.id > 0) {
                    contacts.value[i] = await contactService.update(c.id, payload)
                } else if (c.lastName || c.firstName) {
                    contacts.value[i] = await contactService.create(payload)
                }
            }
        } finally {
            savingContacts.value = false
        }
    }
    async function saveAddresses(): Promise<void> {
        if (savingAddresses.value) return
        savingAddresses.value = true
        try {
            for (let i = 0; i < addresses.value.length; i++) {
                const a = addresses.value[i]
                if (!a) continue
                const payload = { label: a.label, street: a.street, streetComplement: a.streetComplement, postalCode: a.postalCode, city: a.city, country: a.country, ...owner }
                if (a.id && a.id > 0) {
                    addresses.value[i] = await addressService.update(a.id, payload)
                } else if (a.street || a.city || a.postalCode) {
                    addresses.value[i] = await addressService.create(payload)
                }
            }
        } finally {
            savingAddresses.value = false
        }
    }

    async function load(): Promise<void> {
        contacts.value = await contactService.getByOwner(owner)
        addresses.value = await addressService.getByOwner(owner)
    }

    return {
        contacts,
        addresses,
        savingContacts,
        savingAddresses,
        onContactInput,
        addContact,
        removeContact,
        saveContacts,
        onAddressInput,
        addAddress,
        removeAddress,
        saveAddresses,
        load,
        // Suppression de bloc avec confirmation (modal partagée contact/adresse).
        removeModalOpen,
        removeModalTitle,
        removeModalMessage,
        askRemoveContact,
        askRemoveAddress,
        confirmRemove,
    }
}
