<template>
    <div>
        <!-- En-tete : retour repertoire + nom du client + actions (Modifier / Archiver|Restaurer). -->
        <div class="flex items-center gap-3 pt-11">
            <MalioButtonIcon
                icon="mdi:arrow-left-bold"
                icon-size="24"
                variant="ghost"
                v-bind="{ ariaLabel: t('commercial.clients.consultation.back') }"
                @click="goBack"
            />
            <h1 class="text-[30px] font-semibold text-m-primary">{{ headerTitle }}</h1>

            <!-- gap-12 = 48px : meme espacement que Ajouter / Filtres du repertoire. -->
            <div class="ml-auto flex items-center gap-12">
                <MalioButton
                    v-if="canEdit"
                    variant="secondary"
                    icon-name="mdi:pencil-outline"
                    icon-position="left"
                    :label="t('commercial.clients.action.edit')"
                    @click="goEdit"
                />
                <MalioButton
                    v-if="showArchive"
                    variant="secondary"
                    icon-name="mdi:archive-arrow-down-outline"
                    icon-position="left"
                    :label="t('commercial.clients.action.archive')"
                    @click="askToggleArchive"
                />
                <MalioButton
                    v-if="showRestore"
                    variant="secondary"
                    icon-name="mdi:archive-arrow-up-outline"
                    icon-position="left"
                    :label="t('commercial.clients.action.restore')"
                    @click="askToggleArchive"
                />
            </div>
        </div>

        <!-- Etats de chargement / introuvable. -->
        <p v-if="loading" class="mt-12 text-center text-black/60">{{ t('commercial.clients.consultation.loading') }}</p>
        <p v-else-if="error" class="mt-12 text-center text-m-danger">{{ t('commercial.clients.consultation.notFound') }}</p>

        <template v-else-if="client">
            <!-- ── Formulaire principal (lecture seule) ──────────────────────── -->
            <div class="mt-[48px] grid grid-cols-3 xl:grid-cols-4 gap-x-[44px] gap-y-4">
                <MalioInputText
                    :model-value="client.companyName"
                    :label="t('commercial.clients.form.main.companyName')"
                    readonly
                />
                <MalioSelectCheckbox
                    :model-value="categoryIris"
                    :options="mainCategoryOptions"
                    :label="t('commercial.clients.form.main.categories')"
                    :display-tag="true"
                    readonly
                />
                <!-- Relation toujours affichee (vide = « Aucun »), comme en edition. -->
                <MalioSelect
                    :model-value="relation.type"
                    :options="relationOptions"
                    :label="t('commercial.clients.form.main.relation')"
                    :empty-option-label="t('commercial.clients.form.main.relationNone')"
                    readonly
                />
                <!-- Nom du distributeur/courtier : conditionnel (libelle type-dependant,
                     aucune valeur sans relation — meme comportement qu'en edition). -->
                <MalioInputText
                    v-if="relation.type"
                    :model-value="relation.name"
                    :label="relation.type === 'distributeur' ? t('commercial.clients.form.main.distributorName') : t('commercial.clients.form.main.brokerName')"
                    readonly
                />
                <MalioCheckbox
                    :model-value="client.triageService === true"
                    :label="t('commercial.clients.form.main.triageService')"
                    group-class="self-center"
                    readonly
                />
            </div>

            <!-- ── Onglets (navigation libre, tout en lecture seule) ─────────── -->
            <MalioTabList v-model="activeTab" :tabs="tabs" :max-visible-tabs="5" :max-width="1100" class="mt-[60px]">
                <!-- Onglet Information -->
                <template #information>
                    <div class="mt-12 grid grid-cols-4 gap-x-[44px] gap-y-4 bg-white py-4 pl-[28px] pr-[60px] shadow-[0_4px_4px_0_rgba(0,0,0,0.25)]">
                        <!-- pt-1/pb-1 alignent le textarea (h-full) en haut ET en bas
                             sur les inputs (champ 40px centre dans un h-12 -> ~4px de
                             coussin de chaque cote). -->
                        <MalioInputTextArea
                            :model-value="information.description"
                            :label="t('commercial.clients.form.information.description')"
                            resize="none"
                            group-class="row-span-2 pt-1 pb-1"
                            text-input="h-full text-lg"
                            readonly
                        />
                        <MalioInputText
                            :model-value="information.competitors"
                            :label="t('commercial.clients.form.information.competitors')"
                            readonly
                        />
                        <MalioDate
                            :model-value="information.foundedAt"
                            :label="t('commercial.clients.form.information.foundedAt')"
                            readonly
                        />
                        <MalioInputText
                            :model-value="information.employeesCount"
                            :label="t('commercial.clients.form.information.employeesCount')"
                            readonly
                        />
                        <MalioInputAmount
                            :model-value="information.revenueAmount"
                            :label="t('commercial.clients.form.information.revenueAmount')"
                            readonly
                        />
                        <MalioInputText
                            :model-value="information.directorName"
                            :label="t('commercial.clients.form.information.directorName')"
                            readonly
                        />
                        <MalioInputAmount
                            :model-value="information.profitAmount"
                            :label="t('commercial.clients.form.information.profitAmount')"
                            readonly
                        />
                    </div>
                </template>

                <!-- Onglet Contact -->
                <template #contact>
                    <div class="mt-12 flex flex-col gap-6">
                        <ClientContactBlock
                            v-for="(contact, index) in contacts"
                            :key="contact.id ?? index"
                            :model-value="contact"
                            :title="t('commercial.clients.form.contact.title', { n: index + 1 })"
                            readonly
                        />
                    </div>
                </template>

                <!-- Onglet Adresse -->
                <template #address>
                    <div class="mt-12 flex flex-col gap-6">
                        <ClientAddressBlock
                            v-for="(view, index) in addressViews"
                            :key="view.draft.id ?? index"
                            :model-value="view.draft"
                            :title="t('commercial.clients.form.address.title', { n: index + 1 })"
                            :category-options="view.categoryOptions"
                            :site-options="allSiteOptions"
                            :contact-options="contactOptions"
                            :country-options="countryOptions"
                            readonly
                        />
                    </div>
                </template>

                <!-- Onglet Comptabilite (present uniquement si accounting.view). -->
                <template v-if="canAccountingView" #accounting>
                    <div class="mt-12 flex flex-col gap-6">
                        <div class="bg-white py-4 pl-[28px] pr-[60px] shadow-[0_4px_4px_0_rgba(0,0,0,0.25)]">
                            <div class="grid grid-cols-4 gap-x-[44px] gap-y-4">
                                <MalioInputText
                                    :model-value="accounting.siren"
                                    :label="t('commercial.clients.form.accounting.siren')"
                                    :mask="SIREN_MASK"
                                    readonly
                                />
                                <MalioInputText
                                    :model-value="accounting.accountNumber"
                                    :label="t('commercial.clients.form.accounting.accountNumber')"
                                    readonly
                                />
                                <MalioSelect
                                    :model-value="accounting.tvaModeIri"
                                    :options="tvaModeOptions"
                                    :label="t('commercial.clients.form.accounting.tvaMode')"
                                    empty-option-label=""
                                    readonly
                                />
                                <MalioInputText
                                    :model-value="accounting.nTva"
                                    :label="t('commercial.clients.form.accounting.nTva')"
                                    readonly
                                />
                                <MalioSelect
                                    :model-value="accounting.paymentDelayIri"
                                    :options="paymentDelayOptions"
                                    :label="t('commercial.clients.form.accounting.paymentDelay')"
                                    empty-option-label=""
                                    readonly
                                />
                                <MalioSelect
                                    :model-value="accounting.paymentTypeIri"
                                    :options="paymentTypeOptions"
                                    :label="t('commercial.clients.form.accounting.paymentType')"
                                    empty-option-label=""
                                    readonly
                                />
                                <MalioSelect
                                    v-if="accounting.bankIri"
                                    :model-value="accounting.bankIri"
                                    :options="bankOptions"
                                    :label="t('commercial.clients.form.accounting.bank')"
                                    empty-option-label=""
                                    readonly
                                />
                            </div>
                        </div>

                        <!-- Blocs RIB (0..n), lecture seule. -->
                        <div
                            v-for="(rib, index) in ribs"
                            :key="rib.id ?? index"
                            class="bg-white py-4 pl-[28px] pr-[60px] shadow-[0_4px_4px_0_rgba(0,0,0,0.25)]"
                        >
                            <div class="grid grid-cols-4 gap-x-[44px] gap-y-4">
                                <MalioInputText
                                    :model-value="rib.label"
                                    :label="t('commercial.clients.form.accounting.ribLabel')"
                                    readonly
                                />
                                <MalioInputText
                                    :model-value="rib.bic"
                                    :label="t('commercial.clients.form.accounting.ribBic')"
                                    readonly
                                />
                                <MalioInputText
                                    :model-value="rib.iban"
                                    :label="t('commercial.clients.form.accounting.ribIban')"
                                    readonly
                                />
                            </div>
                        </div>
                    </div>
                </template>

                <!-- Onglets non encore implementes : frame vide (navigation libre). -->
                <template #transport><ComingSoonPlaceholder /></template>
                <template #statistics><ComingSoonPlaceholder /></template>
                <template #reports><ComingSoonPlaceholder /></template>
                <template #exchanges><ComingSoonPlaceholder /></template>
            </MalioTabList>
        </template>

        <!-- Modal de confirmation Archiver / Restaurer. -->
        <MalioModal v-model="confirmOpen" modal-class="max-w-md">
            <template #header>
                <h2 class="text-[24px] font-bold">
                    {{ isArchived ? t('commercial.clients.consultation.confirmRestore.title') : t('commercial.clients.consultation.confirmArchive.title') }}
                </h2>
            </template>
            <p>{{ isArchived ? t('commercial.clients.consultation.confirmRestore.message') : t('commercial.clients.consultation.confirmArchive.message') }}</p>
            <template #footer>
                <MalioButton
                    variant="secondary"
                    button-class="flex-1"
                    :label="t('commercial.clients.form.confirmDelete.cancel')"
                    @click="confirmOpen = false"
                />
                <MalioButton
                    :variant="isArchived ? 'primary' : 'danger'"
                    button-class="flex-1"
                    :label="t('commercial.clients.form.confirmDelete.confirm')"
                    :disabled="toggling"
                    @click="confirmToggleArchive"
                />
            </template>
        </MalioModal>
    </div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useClient } from '~/modules/commercial/composables/useClient'
import { buildClientFormTabKeys, isRibRequiredForPaymentType } from '~/modules/commercial/utils/forms/clientFormRules'
import { readHistoryTab } from '~/shared/utils/historyTab'
import {
    canEditClient,
    categoryOptionsOf,
    contactOptionsOf,
    mapAccountingDraft,
    mapAddressView,
    mapContactToDraft,
    mapRibToDraft,
    paymentTypeCodeOf,
    referentialOptionOf,
    relationOf,
    showArchiveAction,
    showRestoreAction,
    type ClientDetail,
    type SelectOption,
} from '~/modules/commercial/utils/forms/clientConsultation'
import { emptyAddress, emptyContact } from '~/modules/commercial/types/clientForm'

// Masque d'affichage (purement visuel, la donnee reste celle du serveur).
const SIREN_MASK = '#########'

const { t } = useI18n()
const route = useRoute()
const router = useRouter()
const toast = useToast()
const { can, canAny } = usePermissions()
const authStore = useAuthStore()

// Gating de la route : la consultation exige `view`. Usine (sans view) est
// redirige vers le repertoire (lui-meme protege). Cf. matrice § 2.7.
if (!can('commercial.clients.view')) {
    await navigateTo('/clients')
}

const clientId = route.params.id as string

const { client, loading, error, load, archive, restore } = useClient(clientId)

// ── Permissions / visibilite des actions ───────────────────────────────────
const canAccountingView = computed(() => can('commercial.clients.accounting.view'))
const canEdit = computed(() => canEditClient(canAny))
const isArchived = computed(() => client.value?.isArchived === true)
const showArchive = computed(() => showArchiveAction(can, isArchived.value))
const showRestore = computed(() => showRestoreAction(can, isArchived.value))

const headerTitle = computed(() => client.value?.companyName ?? t('commercial.clients.consultation.title'))

// ── Donnees derivees du payload (lecture seule) ────────────────────────────
const relation = computed(() => (client.value ? relationOf(client.value) : { type: null, name: null }))
const categoryIris = computed(() => (client.value?.categories ?? []).map(c => c['@id']))

const information = computed(() => ({
    description: client.value?.description ?? null,
    competitors: client.value?.competitors ?? null,
    // MalioDate attend strictement YYYY-MM-DD : on tronque l'ISO datetime renvoye.
    foundedAt: client.value?.foundedAt ? client.value.foundedAt.slice(0, 10) : null,
    employeesCount: client.value?.employeesCount != null ? String(client.value.employeesCount) : null,
    revenueAmount: client.value?.revenueAmount ?? null,
    profitAmount: client.value?.profitAmount ?? null,
    directorName: client.value?.directorName ?? null,
}))

// Chaque bloc reste visible meme vide en consultation : si la collection est
// vide, on affiche un bloc vierge en lecture seule (pas de message « Aucun … »).
const contacts = computed(() => {
    const list = (client.value?.contacts ?? []).map(mapContactToDraft)
    return list.length ? list : [emptyContact()]
})
// Vue par adresse : brouillon + options (sites/categories) propres a l'adresse.
const addressViews = computed(() => {
    const views = (client.value?.addresses ?? []).map(mapAddressView)
    return views.length ? views : [{ draft: emptyAddress(), siteOptions: [], categoryOptions: [] }]
})
// Exception au placeholder ci-dessus : on n'affiche AUCUN bloc RIB quand le
// client n'en a pas. Pas de bloc vierge fantome en consultation.
// ERP-121 : un client peut desormais conserver des RIB « dormants » apres etre
// repasse hors-LCR (on ne les supprime plus). En consultation, decision metier =
// on les masque TOTALEMENT : on n'affiche les RIB que si le type de reglement
// courant est LCR (le `code` est embarque sous client:read:accounting).
const ribs = computed(() =>
    isRibRequiredForPaymentType(paymentTypeCodeOf(client.value?.paymentType))
        ? (client.value?.ribs ?? []).map(mapRibToDraft)
        : [],
)
// Draft comptable (tout null si l'utilisateur n'a pas accounting.view).
const accounting = computed(() => mapAccountingDraft(client.value ?? ({} as ClientDetail)))

// ── Options des selects (construites depuis l'EMBED, jamais via un GET de
//    referentiel : /categories et /sites sont en 403 pour les roles metier
//    non-admin, ce qui laisserait les libelles vides). ───────────────────────
const mainCategoryOptions = computed(() => categoryOptionsOf(client.value?.categories))
const contactOptions = computed(() => contactOptionsOf(client.value?.contacts))

// Liste COMPLETE des sites disponibles, issue de /api/me (groupe me:read — donc
// pas de 403 pour les roles metier, contrairement a GET /sites). Libelle = numero
// de departement (2 premiers chiffres du code postal). Permet d'afficher TOUJOURS
// toutes les cases « Sites » (86 / 17 / 82) dans le bloc adresse, meme celles non
// rattachees a l'adresse consultee (les rattachees restent cochees via siteIris).
const allSiteOptions = computed<SelectOption[]>(() =>
    (authStore.user?.sites ?? []).map(s => ({
        value: `/api/sites/${s.id}`,
        label: (s.postalCode ?? '').slice(0, 2),
    })),
)

const relationOptions = computed<SelectOption[]>(() => [
    { value: 'distributeur', label: t('commercial.clients.form.main.relationDistributor') },
    { value: 'courtier', label: t('commercial.clients.form.main.relationBroker') },
])

// Pays (ERP-116) : options construites depuis l'EMBED des adresses (jamais via
// GET /countries, sur le meme principe que les autres selects de consultation
// — en 403 pour les roles metier non-admin). Valeur = nom du pays stocke tel
// quel dans l'adresse, donc value === label ; suffit a afficher le libelle en
// lecture seule.
const countryOptions = computed<SelectOption[]>(() =>
    [...new Set(
        (client.value?.addresses ?? [])
            .map(a => a.country)
            .filter((c): c is string => !!c),
    )].map(c => ({ value: c, label: c })),
)

// Selects comptables : libelle issu de l'embed (option unique ou vide).
const tvaModeOptions = computed(() => referentialOptionOf(client.value?.tvaMode))
const paymentDelayOptions = computed(() => referentialOptionOf(client.value?.paymentDelay))
const paymentTypeOptions = computed(() => referentialOptionOf(client.value?.paymentType))
const bankOptions = computed(() => referentialOptionOf(client.value?.bank))

// ── Onglets : navigation LIBRE (pas de sequence forcee en consultation) ────
// 4 onglets actifs (Information, Contact, Adresse, + Comptabilite si droit) et
// 4 coquilles (Transport, Statistiques, Rapports, Echanges).
const tabKeys = computed(() => buildClientFormTabKeys(canAccountingView.value, { includeEditOnlyTabs: true }))

const TAB_ICONS: Record<string, string> = {
    information: 'mdi:account-outline',
    contact: 'mdi:account-box-plus-outline',
    address: 'mdi:map-marker-outline',
    transport: 'mdi:truck-delivery-outline',
    accounting: 'mdi:bank-circle-outline',
    statistics: 'mdi:finance',
    reports: 'mdi:file-document-edit-outline',
    exchanges: 'mdi:account-group-outline',
}

const tabs = computed(() => tabKeys.value.map(key => ({
    key,
    label: t(`commercial.clients.tab.${key}`),
    icon: TAB_ICONS[key],
})))

// Onglet initial : repris de l'edition au retour (history.state), sinon Information.
const activeTab = ref(readHistoryTab(tabKeys.value) ?? 'information')

// ── Navigation ─────────────────────────────────────────────────────────────
function goBack(): void {
    router.push('/clients')
}

/** Bascule en edition en conservant l'onglet courant (via history.state). */
function goEdit(): void {
    router.push({ path: `/clients/${clientId}/edit`, state: { tab: activeTab.value } })
}

// ── Archivage / Restauration ────────────────────────────────────────────────
const confirmOpen = ref(false)
const toggling = ref(false)

function askToggleArchive(): void {
    confirmOpen.value = true
}

/**
 * Confirme l'archivage ou la restauration (PATCH isArchived seul). Gere le 409
 * de conflit d'homonyme actif a la restauration (RG-1.23) avec un message dedie.
 */
async function confirmToggleArchive(): Promise<void> {
    if (toggling.value) return
    toggling.value = true
    const restoring = isArchived.value
    try {
        if (restoring) {
            await restore()
            toast.success({ title: t('commercial.clients.toast.restoreSuccess') })
        }
        else {
            await archive()
            toast.success({ title: t('commercial.clients.toast.archiveSuccess') })
        }
        confirmOpen.value = false
    }
    catch (e) {
        const status = (e as { response?: { status?: number } })?.response?.status
        toast.error({
            title: t('commercial.clients.toast.error'),
            message: restoring && status === 409
                ? t('commercial.clients.toast.restoreConflict')
                : t('commercial.clients.toast.error'),
        })
    }
    finally {
        toggling.value = false
    }
}

useHead({ title: headerTitle })

onMounted(load)
</script>
