<template>
    <div>
        <!-- En-tête : retour répertoire + nom + actions. -->
        <div class="flex items-center gap-3 pt-11">
            <MalioButtonIcon
                icon="mdi:arrow-left-bold"
                icon-size="24"
                variant="ghost"
                v-bind="{ ariaLabel: t('transport.carriers.consultation.back') }"
                @click="goBack"
            />
            <h1 class="text-[30px] font-semibold text-m-primary">{{ headerTitle }}</h1>

            <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('transport.carriers.action.edit')"
                    @click="goEdit"
                />
                <MalioButton
                    v-if="showArchive"
                    variant="secondary"
                    icon-name="mdi:archive-arrow-down-outline"
                    icon-position="left"
                    :label="t('transport.carriers.action.archive')"
                    @click="askToggleArchive"
                />
                <MalioButton
                    v-if="showRestore"
                    variant="secondary"
                    icon-name="mdi:archive-arrow-up-outline"
                    icon-position="left"
                    :label="t('transport.carriers.action.restore')"
                    @click="askToggleArchive"
                />
            </div>
        </div>

        <p v-if="loading" class="mt-12 text-center text-black/60">{{ t('transport.carriers.consultation.loading') }}</p>
        <p v-else-if="error" class="mt-12 text-center text-m-danger">{{ t('transport.carriers.consultation.notFound') }}</p>

        <template v-else-if="carrier">
            <!-- ── Bloc principal (lecture seule) — même disposition que l'ajout ── -->
            <div class="mt-[48px] grid grid-cols-3 xl:grid-cols-4 gap-x-[44px] gap-y-4">
                <MalioInputText :model-value="main.name" :label="t('transport.carriers.form.main.name')" readonly />

                <!-- Cas LIOT : seul le champ immatriculations. -->
                <MalioInputText
                    v-if="isLiot"
                    :model-value="main.liotPlates"
                    :label="t('transport.carriers.form.main.liotPlates')"
                    readonly
                />

                <!-- Cas standard : certification + décharge (col 3 réservée) + affrètement (col 4). -->
                <template v-if="!isLiot">
                    <MalioInputText
                        :model-value="certificationLabel"
                        :label="t('transport.carriers.form.main.certificationType')"
                        readonly
                    />

                    <!-- Colonne 3 réservée à la décharge (si AUTRE), sinon vide (xl). -->
                    <MalioInputText
                        v-if="main.certificationType === 'AUTRE'"
                        :model-value="dischargeLabel"
                        :label="t('transport.carriers.form.main.discharge')"
                        readonly
                    />
                    <div v-else class="hidden xl:block"></div>

                    <!-- Affréter : colonne 4, centré (h-12) comme à l'ajout. -->
                    <div class="flex h-12 items-center">
                        <MalioCheckbox
                            id="carrier-view-chartered"
                            :label="t('transport.carriers.form.main.isChartered')"
                            :model-value="main.isChartered"
                            readonly
                            :reserve-message-space="false"
                        />
                    </div>

                    <!-- Champs d'affrètement (ligne 2) si affrété. -->
                    <template v-if="main.isChartered">
                        <MalioInputText :model-value="indexationDisplay" :label="t('transport.carriers.form.main.indexationRate')" readonly />
                        <!-- Contenant : radios désactivés (lecture seule), aligné sur l'ajout / la modif. -->
                        <div>
                            <div class="flex h-12 items-center gap-4">
                                <MalioRadioButton
                                    :model-value="main.containerType"
                                    name="carrier-view-container"
                                    value="BENNE"
                                    :label="t('transport.carriers.containerType.BENNE')"
                                    readonly
                                    group-class="mt-0"
                                />
                                <MalioRadioButton
                                    :model-value="main.containerType"
                                    name="carrier-view-container"
                                    value="FOND_MOUVANT"
                                    :label="t('transport.carriers.containerType.FOND_MOUVANT')"
                                    readonly
                                    group-class="mt-0"
                                />
                            </div>
                        </div>
                        <MalioInputText :model-value="main.volumeM3" :label="t('transport.carriers.form.main.volumeM3')" readonly />
                    </template>
                </template>
            </div>

            <!-- ── Onglets (Adresses · Contacts · Prix) — ouvre sur Adresses ──── -->
            <MalioTabList v-model="activeTab" :tabs="tabs" class="mt-[60px]">
                <template #addresses>
                    <div class="mt-12 flex flex-col gap-6">
                        <!-- Adresse UNIQUE (ERP-172). -->
                        <CarrierAddressBlock
                            :model-value="address"
                            :country-options="countryOptionsFor(address.country)"
                            readonly
                        />
                    </div>
                </template>

                <template #contacts>
                    <div class="mt-12 flex flex-col gap-6">
                        <CarrierContactBlock
                            v-for="(contact, index) in contacts"
                            :key="index"
                            :model-value="contact"
                            readonly
                        />
                    </div>
                </template>

                <!-- Prix : tableau présentationnel regroupé par contenant + export. -->
                <template #prices>
                    <div class="mt-12 flex flex-col gap-6">
                        <!-- Police / bordures / radius alignés sur MalioDataTable (header
                             16px, corps 14px). 1re colonne « Contenant » : libellé du
                             groupe (Fond Mouvant / Benne) fusionné en rowspan ; séparateur
                             épais entre les deux groupes. -->
                        <table class="w-full table-fixed border-separate border-spacing-0 overflow-hidden rounded-malio border border-black text-left text-black">
                            <!-- Répartition (table-fixed) : « Type de transport » un peu plus
                                 large ; Transporteurs et Adresse livraisons larges ; Forfait /
                                 Tonne / Indexation / État réduits. -->
                            <colgroup>
                                <col class="w-[170px]" />
                                <col class="w-[20%]" />
                                <col class="w-[11%]" />
                                <col class="w-[24%]" />
                                <col class="w-[9%]" />
                                <col class="w-[9%]" />
                                <col class="w-[9%]" />
                                <col class="w-[9%]" />
                            </colgroup>
                            <thead>
                                <tr>
                                    <!-- En-tête centré pour matcher les cellules fusionnées Benne / Fond mouvant. -->
                                    <th class="border-b border-r border-black bg-m-surface px-3 py-3 text-center align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.group') }}</th>
                                    <th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.carrier') }}</th>
                                    <th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.aproOrSite') }}</th>
                                    <th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.delivery') }}</th>
                                    <th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.forfait') }}</th>
                                    <th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.tonne') }}</th>
                                    <th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.indexation') }}</th>
                                    <th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.state') }}</th>
                                </tr>
                            </thead>
                            <tbody>
                                <template v-for="(group, gi) in priceGroups" :key="group.label">
                                    <tr
                                        v-for="(row, i) in group.rows"
                                        :key="`${gi}-${i}`"
                                    >
                                        <!-- Cellule de groupe fusionnée (rowspan), centrée verticalement ;
                                             séparateur épais en bas entre les groupes (sauf dernier). -->
                                        <td
                                            v-if="i === 0"
                                            :rowspan="group.rows.length"
                                            class="border-r border-black px-3 text-center align-middle text-[14px] font-medium"
                                            :class="groupBorder(gi)"
                                        >
                                            {{ group.label }}
                                        </td>
                                        <td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ headerTitle }}</td>
                                        <td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.apro }}</td>
                                        <td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.delivery }}</td>
                                        <td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.forfait }}</td>
                                        <td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.tonne }}</td>
                                        <td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.indexation }}</td>
                                        <td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.state }}</td>
                                    </tr>
                                </template>
                                <tr v-if="!hasPrices">
                                    <td colspan="8" class="px-3 py-4 text-center text-[14px] text-m-muted">
                                        {{ t('transport.carriers.consultation.price.empty') }}
                                    </td>
                                </tr>
                            </tbody>
                        </table>

                        <div v-if="hasPrices" class="flex justify-center">
                            <MalioButton
                                variant="primary"
                                :label="t('transport.carriers.consultation.price.export')"
                                :disabled="exporting"
                                @click="exportPrices"
                            />
                        </div>
                    </div>
                </template>
            </MalioTabList>
        </template>

        <!-- Modal de confirmation archivage / restauration. -->
        <MalioModal v-model="confirmArchive.open" modal-class="max-w-md">
            <template #header>
                <h2 class="text-[24px] font-bold">{{ confirmArchive.title }}</h2>
            </template>
            <p>{{ confirmArchive.message }}</p>
            <template #footer>
                <MalioButton
                    variant="secondary"
                    button-class="flex-1"
                    :label="t('transport.carriers.form.confirmDelete.cancel')"
                    @click="confirmArchive.open = false"
                />
                <MalioButton
                    variant="danger"
                    button-class="flex-1"
                    :label="confirmArchive.confirmLabel"
                    @click="runToggleArchive"
                />
            </template>
        </MalioModal>
    </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue'
import CarrierAddressBlock from '~/modules/transport/components/CarrierAddressBlock.vue'
import CarrierContactBlock from '~/modules/transport/components/CarrierContactBlock.vue'
import { useCarrier } from '~/modules/transport/composables/useCarrier'
import {
    canEditCarrier,
    labelOfRelation,
    mapAddressToDraft,
    mapContactToDraft,
    mapMainToDraft,
    showArchiveAction,
    showRestoreAction,
    type CarrierPriceRead,
    type Relation,
} from '~/modules/transport/utils/forms/carrierMappers'
import { extractApiErrorMessage } from '~/shared/utils/api'

interface SelectOption {
    value: string
    label: string
}

const { t } = useI18n()
const route = useRoute()
const router = useRouter()
const toast = useToast()
const api = useApi()
const { can } = usePermissions()

const carrierId = route.params.id as string
const { carrier, loading, error, load, archive, restore } = useCarrier(carrierId)

const isArchived = computed(() => carrier.value?.isArchived ?? false)
const canEdit = computed(() => canEditCarrier(can))
const showArchive = computed(() => showArchiveAction(can, isArchived.value))
const showRestore = computed(() => showRestoreAction(can, isArchived.value))

const headerTitle = computed(() => carrier.value?.name || t('transport.carriers.consultation.title'))
useHead({ title: t('transport.carriers.consultation.title') })

// ── Bloc principal mappé (lecture seule) ─────────────────────────────────────
const main = computed(() => mapMainToDraft(carrier.value ?? { id: 0, '@id': '' }))
const isLiot = computed(() => main.value.name.trim().toUpperCase() === 'LIOT')
const certificationLabel = computed(() => main.value.certificationType
    ? t(`transport.carriers.certification.${main.value.certificationType}`)
    : '')
// Indexation affichée avec le « % » (comme l'icône du champ amount de l'ajout).
const indexationDisplay = computed(() => main.value.indexationRate ? `${main.value.indexationRate} %` : '')
// Décharge : nom du fichier embarqué si présent (sinon vide ; la colonne reste réservée).
const dischargeLabel = computed(() => {
    const doc = carrier.value?.dischargeDocument
    if (doc && typeof doc !== 'string') {
        const meta = doc as Record<string, unknown>
        return String(meta.originalFilename ?? meta.name ?? '')
    }
    return ''
})

// ── Onglets : Adresses · Contacts · Prix (ouvre sur Adresses, pas de Qualimat) ──
const activeTab = ref('addresses')
const TAB_ICONS: Record<string, string> = {
    addresses: 'mdi:map-marker-outline',
    contacts: 'mdi:account-box-plus-outline',
    prices: 'mdi:payment',
}
const tabs = computed(() => ['addresses', 'contacts', 'prices'].map(key => ({
    key,
    label: t(`transport.carriers.tab.${key}`),
    icon: TAB_ICONS[key],
})))

// Adresse UNIQUE (ERP-172) : un seul bloc en lecture seule (vide si pas d'adresse).
const address = computed(() => carrier.value?.address
    ? mapAddressToDraft(carrier.value.address)
    : mapAddressToDraft({ id: 0, '@id': '' }))
const contacts = computed(() => {
    const list = (carrier.value?.contacts ?? []).map(mapContactToDraft)
    return list.length > 0 ? list : [mapContactToDraft({ id: 0, '@id': '' })]
})

/** Pays : une seule option (valeur courante), suffisant pour l'affichage readonly. */
function countryOptionsFor(country: string): SelectOption[] {
    return country ? [{ value: country, label: country }] : []
}

// ── Tableau Prix consultation (regroupé par contenant Fond Mouvant / Benne) ───
const PRICE_GROUP_ORDER = ['FOND_MOUVANT', 'BENNE'] as const

interface PriceRowView {
    apro: string
    delivery: string
    forfait: string
    tonne: string
    indexation: string
    state: string
}

/** Groupe de prix d'un même contenant (Fond Mouvant / Benne) — cellule fusionnée. */
interface PriceGroupView {
    label: string
    rows: PriceRowView[]
}

/** Formate un montant décimal en « 1 000,00 € » (chaîne vide si absent). */
function formatAmount(value: string | null | undefined): string {
    if (!value) {
        return ''
    }
    const n = Number(value)
    if (Number.isNaN(n)) {
        return ''
    }
    return `${n.toLocaleString('fr-FR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} €`
}

/** Code du site = département (2 premiers chiffres du code postal, ex: 86 / 17 / 82). */
function siteCode(relation: Relation): string {
    if (!relation || typeof relation === 'string') {
        return ''
    }
    const postalCode = relation.postalCode as string | undefined
    return postalCode ? postalCode.slice(0, 2) : ''
}

/**
 * Construit une ligne d'affichage depuis un prix embarqué (maquette Prix) :
 *  - « Adresse sites » = le CODE du site (département, ex: 86 / 17 / 82) ;
 *  - « Adresse livraisons » = l'adresse (voie) du client/fournisseur ;
 *  - le prix tombe dans Forfait € OU Tonne € selon `pricingUnit`.
 */
function toPriceRow(price: CarrierPriceRead): PriceRowView {
    const isClient = price.direction === 'CLIENT'
    return {
        apro: isClient ? siteCode(price.departureSite) : siteCode(price.deliverySite),
        delivery: isClient ? labelOfRelation(price.clientDeliveryAddress) : labelOfRelation(price.supplierSupplyAddress),
        forfait: price.pricingUnit === 'FORFAIT' ? formatAmount(price.price) : '',
        tonne: price.pricingUnit === 'TONNE' ? formatAmount(price.price) : '',
        // CarrierPrice n'a pas de taux d'indexation propre → on affiche celui du
        // transporteur (formulaire principal). À faire évoluer si un taux par prix
        // est requis (gap back).
        indexation: main.value.indexationRate ? `${main.value.indexationRate} %` : '',
        state: price.priceState ? t(`transport.carriers.form.price.state${stateSuffix(price.priceState)}`) : '',
    }
}

/** EN_COURS → EnCours, VALIDE → Valide, NON_VALIDE → NonValide (clés i18n existantes). */
function stateSuffix(state: string): string {
    const map: Record<string, string> = { EN_COURS: 'EnCours', VALIDE: 'Valide', NON_VALIDE: 'NonValide' }
    return map[state] ?? ''
}

// Prix regroupés par contenant (Fond Mouvant puis Benne) — une cellule fusionnée
// par groupe (rowspan) à gauche, conformément à la maquette.
const priceGroups = computed<PriceGroupView[]>(() => {
    const list = carrier.value?.prices ?? []
    return PRICE_GROUP_ORDER
        .map(container => ({
            label: t(`transport.carriers.containerType.${container}`),
            rows: list.filter(p => p.containerType === container).map(toPriceRow),
        }))
        .filter(group => group.rows.length > 0)
})

const hasPrices = computed(() => priceGroups.value.length > 0)

/**
 * Bordure basse d'une cellule de données :
 *  - ligne interne d'un groupe → fine grise ;
 *  - dernière ligne d'un groupe NON final → épaisse noire (séparateur de groupe) ;
 *  - dernière ligne du DERNIER groupe → aucune (le cadre du tableau s'en charge,
 *    évite la double bordure tout en bas).
 */
function dataBorder(group: PriceGroupView, i: number, gi: number): string {
    const isLastRow = i === group.rows.length - 1
    const isLastGroup = gi === priceGroups.value.length - 1
    if (!isLastRow) {
        return 'border-b border-m-muted/30'
    }
    return isLastGroup ? '' : 'border-b-2 border-black'
}

/** Bordure basse de la cellule de groupe fusionnée (séparateur épais sauf dernier groupe). */
function groupBorder(gi: number): string {
    return gi === priceGroups.value.length - 1 ? '' : 'border-b-2 border-black'
}

// ── Export XLSX des prix ─────────────────────────────────────────────────────
const exporting = ref(false)

async function exportPrices(): Promise<void> {
    if (exporting.value) return
    exporting.value = true
    try {
        const blob = await api.get<Blob>(`/carriers/${carrierId}/prices/export.xlsx`, {}, {
            responseType: 'blob',
            toast: false,
        } as unknown as Parameters<typeof api.get>[2])
        triggerDownload(blob, `transporteur-${carrierId}-prix.xlsx`)
    }
    catch {
        toast.error({ title: t('transport.carriers.toast.error'), message: t('transport.carriers.toast.exportError') })
    }
    finally {
        exporting.value = false
    }
}

function triggerDownload(blob: Blob, filename: string): void {
    const url = URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = filename
    document.body.appendChild(link)
    link.click()
    link.remove()
    URL.revokeObjectURL(url)
}

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

function goEdit(): void {
    router.push(`/carriers/${carrierId}/edit`)
}

const confirmArchive = reactive({ open: false, title: '', message: '', confirmLabel: '' })

function askToggleArchive(): void {
    const archiving = !isArchived.value
    confirmArchive.title = archiving ? t('transport.carriers.action.archive') : t('transport.carriers.action.restore')
    confirmArchive.message = archiving
        ? t('transport.carriers.consultation.confirmArchive.message')
        : t('transport.carriers.consultation.confirmRestore.message')
    confirmArchive.confirmLabel = archiving ? t('transport.carriers.action.archive') : t('transport.carriers.action.restore')
    confirmArchive.open = true
}

async function runToggleArchive(): Promise<void> {
    const archiving = !isArchived.value
    confirmArchive.open = false
    try {
        await (archiving ? archive() : restore())
        toast.success({
            title: archiving
                ? t('transport.carriers.toast.archiveSuccess')
                : t('transport.carriers.toast.restoreSuccess'),
        })
    }
    catch (err) {
        // Surface le message back (ex. 409 « homonyme actif » à la restauration),
        // propagé exprès par useCarrier ; fallback générique sinon.
        const data = (err as { response?: { _data?: unknown } })?.response?._data
        toast.error({
            title: t('transport.carriers.toast.error'),
            message: extractApiErrorMessage(data) || undefined,
        })
    }
}

onMounted(load)
</script>
