<template>
    <div>
        <!-- En-tete : retour vers le repertoire + titre. -->
        <div class="flex items-center gap-3 pt-11">
            <MalioButtonIcon
                icon="mdi:arrow-left-bold"
                icon-size="24"
                variant="ghost"
                v-bind="{ ariaLabel: t('technique.providers.form.back') }"
                @click="goBack"
            />
            <h1 class="text-[30px] font-semibold text-m-primary">{{ t('technique.providers.form.title') }}</h1>
        </div>

        <!-- ── Formulaire principal (pre-onglets) ─────────────────────────────
             Sans validation de ce bloc, les onglets restent inaccessibles. Au
             succes du POST, les champs passent en lecture seule et on bascule
             automatiquement sur l'onglet Contact (PAS d'onglet Information au M3).
             Selecteur de site present ici (RG-3.03, relation directe). -->
        <div class="mt-[48px] grid grid-cols-3 xl:grid-cols-4 gap-x-[44px] gap-y-4">
            <MalioInputText
                v-model="main.companyName"
                :label="t('technique.providers.form.main.companyName')"
                :required="true"
                :readonly="mainLocked"
                :error="mainErrors.errors.companyName"
            />
            <MalioSelectCheckbox
                :model-value="main.categoryIris"
                :options="referentials.categories.value"
                :label="t('technique.providers.form.main.categories')"
                :display-tag="true"
                :readonly="mainLocked"
                :required="true"
                :error="mainErrors.errors.categories"
                @update:model-value="(v: (string | number)[]) => main.categoryIris = v.map(String)"
            />
            <MalioSelectCheckbox
                :model-value="main.siteIris"
                :options="referentials.sites.value"
                :label="t('technique.providers.form.main.sites')"
                :display-tag="true"
                :readonly="mainLocked"
                :required="true"
                :error="mainErrors.errors.sites"
                @update:model-value="(v: (string | number)[]) => main.siteIris = v.map(String)"
            />
        </div>

        <div v-if="!mainLocked" class="mt-12 flex justify-center">
            <MalioButton
                variant="primary"
                :label="t('technique.providers.form.submit')"
                :disabled="mainSubmitting"
                @click="submitMain"
            />
        </div>

        <!-- ── Onglets a validation incrementale ─────────────────────────────
             Onglet Contact actif (ERP-142) ; Adresse / Comptabilite arrivent aux
             tickets ERP-143 / 144 : placeholders « A venir » pour l'instant. -->
        <MalioTabList v-model="activeTab" :tabs="tabs" class="mt-[60px]">
            <!-- Onglet Contact : saisie multi-contacts (blocs ajoutables). -->
            <template #contact>
                <div class="mt-12 flex flex-col gap-6">
                    <ProviderContactBlock
                        v-for="(contact, index) in contacts"
                        :key="index"
                        :model-value="contact"
                        :removable="index > 0"
                        :readonly="isValidated('contact')"
                        :errors="contactErrors[index]"
                        @update:model-value="(v) => contacts[index] = v"
                        @remove="askRemoveContact(index)"
                    />
                    <div v-if="!isValidated('contact')" class="flex justify-center gap-6">
                        <MalioButton
                            variant="secondary"
                            icon-name="mdi:add-bold"
                            icon-position="left"
                            :label="t('technique.providers.form.contact.add')"
                            :disabled="!canAddContact"
                            @click="addContact"
                        />
                        <MalioButton
                            variant="primary"
                            :label="t('technique.providers.form.submit')"
                            :disabled="tabSubmitting"
                            @click="onSubmitContacts"
                        />
                    </div>
                </div>
            </template>
            <!-- Onglet Adresse : saisie multi-adresses (blocs ajoutables). -->
            <template #address>
                <div class="mt-12 flex flex-col gap-6">
                    <ProviderAddressBlock
                        v-for="(address, index) in addresses"
                        :key="index"
                        :model-value="address"
                        :category-options="referentials.categories.value"
                        :site-options="referentials.sites.value"
                        :contact-options="contactOptions"
                        :country-options="countryOptions"
                        :removable="index > 0"
                        :readonly="isValidated('address')"
                        :errors="addressErrors[index]"
                        @update:model-value="(v) => addresses[index] = v"
                        @remove="askRemoveAddress(index)"
                        @degraded="onAddressDegraded"
                    />
                    <div v-if="!isValidated('address')" class="flex justify-center gap-6">
                        <MalioButton
                            variant="secondary"
                            icon-name="mdi:add-bold"
                            icon-position="left"
                            :label="t('technique.providers.form.address.add')"
                            :disabled="!canAddAddress"
                            @click="addAddress"
                        />
                        <MalioButton
                            variant="primary"
                            :label="t('technique.providers.form.submit')"
                            :disabled="tabSubmitting"
                            @click="onSubmitAddresses"
                        />
                    </div>
                </div>
            </template>
            <template v-if="canAccountingView" #accounting><ComingSoonPlaceholder /></template>
        </MalioTabList>

        <!-- Modal de confirmation generique (suppression d'un bloc contact). -->
        <MalioModal v-model="confirmModal.open" modal-class="max-w-md">
            <template #header>
                <h2 class="text-[24px] font-bold">{{ t('technique.providers.form.confirmDelete.title') }}</h2>
            </template>
            <p>{{ confirmModal.message }}</p>
            <template #footer>
                <MalioButton
                    variant="secondary"
                    button-class="flex-1"
                    :label="t('technique.providers.form.confirmDelete.cancel')"
                    @click="confirmModal.open = false"
                />
                <MalioButton
                    variant="danger"
                    button-class="flex-1"
                    :label="t('technique.providers.form.confirmDelete.confirm')"
                    @click="runConfirm"
                />
            </template>
        </MalioModal>
    </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue'
import { useProviderReferentials, type RefOption } from '~/modules/technique/composables/useProviderReferentials'
import { useProviderForm } from '~/modules/technique/composables/useProviderForm'
import { extractApiErrorMessage } from '~/shared/utils/api'

const { t } = useI18n()
const router = useRouter()
const toast = useToast()
const { can } = usePermissions()

useHead({ title: t('technique.providers.form.title') })

// Gating de la route : la creation est reservee a `manage` (POST /providers garde
// manage seul — Compta ne cree pas). Compta (accounting seul) et Usine sont
// rediriges vers le repertoire.
if (!can('technique.providers.manage')) {
    await navigateTo('/providers')
}

const referentials = useProviderReferentials()

const {
    main,
    mainLocked,
    mainSubmitting,
    mainErrors,
    canAccountingView,
    tabKeys,
    activeTab,
    unlockedIndex,
    submitMain,
    tabSubmitting,
    isValidated,
    contacts,
    contactErrors,
    canAddContact,
    addContact,
    removeContact,
    submitContacts,
    addresses,
    addressErrors,
    canAddAddress,
    addAddress,
    removeAddress,
    submitAddresses,
} = useProviderForm()

/** Retour vers le repertoire prestataires (fleche d'en-tete). */
function goBack(): void {
    router.push('/providers')
}

/**
 * Message d'erreur a afficher dans un toast a partir d'une erreur d'API. Retourne
 * TOUJOURS une chaine (le composant de toast plante sur `undefined`).
 */
function apiErrorMessage(error: unknown): string {
    const data = (error as { response?: { _data?: unknown } })?.response?._data
    return extractApiErrorMessage(data) || t('technique.providers.toast.error')
}

// ── Onglet Contact ──────────────────────────────────────────────────────────
/** Valide l'onglet Contact ; toast de succes si l'onglet a ete finalise. */
async function onSubmitContacts(): Promise<void> {
    const ok = await submitContacts(error => toast.error({
        title: t('technique.providers.toast.error'),
        message: apiErrorMessage(error),
    }))
    if (ok) {
        toast.success({ title: t('technique.providers.toast.updateSuccess') })
    }
}

function askRemoveContact(index: number): void {
    askConfirm(t('technique.providers.form.confirmDelete.contact'), () => removeContact(index))
}

// ── Onglet Adresse ────────────────────────────────────────────────────────────
// Contacts deja persistes (IRI non nul), rattachables a une adresse (M2M). Le
// libelle reprend le nom complet, a defaut l'email.
const contactOptions = computed<RefOption[]>(() =>
    contacts.value
        .filter(c => c.iri !== null)
        .map(c => ({
            value: c.iri as string,
            label: [c.firstName, c.lastName].filter(Boolean).join(' ') || (c.email ?? ''),
        })),
)

// Pays : France garantie en tete meme si /countries echoue (resilience ERP-102),
// pour rester preselectionnable par defaut sur chaque adresse.
const countryOptions = computed<RefOption[]>(() => {
    const list = referentials.countries.value
    return list.some(c => c.value === 'France')
        ? list
        : [{ value: 'France', label: 'France' }, ...list]
})

const addressDegradedNotified = ref(false)

/** Avertit une seule fois quand l'autocompletion d'adresse bascule en degrade (RG-3.06). */
function onAddressDegraded(): void {
    if (addressDegradedNotified.value) {
        return
    }
    addressDegradedNotified.value = true
    toast.warning({
        title: t('technique.providers.toast.error'),
        message: t('technique.providers.form.address.degraded'),
    })
}

/** Valide l'onglet Adresse ; toast de succes si l'onglet a ete finalise. */
async function onSubmitAddresses(): Promise<void> {
    const ok = await submitAddresses(error => toast.error({
        title: t('technique.providers.toast.error'),
        message: apiErrorMessage(error),
    }))
    if (ok) {
        toast.success({ title: t('technique.providers.toast.updateSuccess') })
    }
}

function askRemoveAddress(index: number): void {
    askConfirm(t('technique.providers.form.confirmDelete.address'), () => removeAddress(index))
}

// ── Modal de confirmation generique ─────────────────────────────────────────
const confirmModal = reactive({
    open: false,
    message: '',
    action: null as null | (() => void),
})

function askConfirm(message: string, action: () => void): void {
    confirmModal.message = message
    confirmModal.action = action
    confirmModal.open = true
}

function runConfirm(): void {
    confirmModal.action?.()
    confirmModal.action = null
    confirmModal.open = false
}

// Icone (Iconify) affichee dans l'onglet, par cle.
const TAB_ICONS: Record<string, string> = {
    contact: 'mdi:account-box-plus-outline',
    address: 'mdi:map-marker-outline',
    accounting: 'mdi:bank-circle-outline',
}

// Onglets desactives tant que le formulaire principal n'est pas valide
// (unlockedIndex = -1 au depart) ; deverrouillage progressif ensuite.
const tabs = computed(() => tabKeys.value.map((key, index) => ({
    key,
    label: t(`technique.providers.tab.${key}`),
    icon: TAB_ICONS[key],
    disabled: index > unlockedIndex.value,
})))

onMounted(() => {
    // Echec du chargement des referentiels non bloquant : les selects restent vides.
    referentials.loadMain().catch(() => {})
})
</script>
