import { describe, it, expect } from 'vitest'
import {
    canEditCarrier,
    iriOf,
    labelOfRelation,
    mapAddressToDraft,
    mapContactToDraft,
    mapMainToDraft,
    mapPriceToDraft,
    showArchiveAction,
    showRestoreAction,
    type CarrierDetail,
} from '../carrierMappers'

/**
 * Tests des mappers détail → brouillons (M4 Transport, ERP-170) : peuplent les écrans
 * Consultation / Modification depuis la SEULE réponse `GET /api/carriers/{id}`, et
 * helpers de visibilité des boutons (Modifier / Archiver / Restaurer) selon la permission.
 */
describe('carrierMappers', () => {
    it('iriOf : objet embarqué, IRI nu, ou null', () => {
        expect(iriOf({ '@id': '/api/clients/3' })).toBe('/api/clients/3')
        expect(iriOf('/api/sites/1')).toBe('/api/sites/1')
        expect(iriOf(null)).toBeNull()
        expect(iriOf(undefined)).toBeNull()
    })

    it('labelOfRelation : name (site) à défaut adresse condensée', () => {
        expect(labelOfRelation({ '@id': '/api/sites/1', name: 'Châtellerault' })).toBe('Châtellerault')
        expect(labelOfRelation({ '@id': '/api/client_addresses/8', street: '1 rue X', postalCode: '86000', city: 'Poitiers' })).toBe('1 rue X · 86000 · Poitiers')
        expect(labelOfRelation('/api/sites/1')).toBe('')
        expect(labelOfRelation(null)).toBe('')
    })

    it('mapMainToDraft : scalaires + IRI décharge / qualimat', () => {
        const detail: CarrierDetail = {
            '@id': '/api/carriers/7',
            id: 7,
            name: 'TRANSPORTS ACME',
            certificationType: 'QUALIMAT',
            isChartered: true,
            indexationRate: '5.00',
            containerType: 'BENNE',
            volumeM3: '30.00',
            dischargeDocument: { '@id': '/api/uploaded_documents/4' },
            qualimatCarrier: { '@id': '/api/qualimat_carriers/42' },
        }
        expect(mapMainToDraft(detail)).toEqual({
            name: 'TRANSPORTS ACME',
            certificationType: 'QUALIMAT',
            isChartered: true,
            indexationRate: '5.00',
            containerType: 'BENNE',
            volumeM3: '30.00',
            liotPlates: '',
            dischargeDocumentIri: '/api/uploaded_documents/4',
            qualimatCarrierIri: '/api/qualimat_carriers/42',
        })
    })

    it('mapAddressToDraft : pays par défaut France si absent', () => {
        expect(mapAddressToDraft({ '@id': '/api/carrier_addresses/3', id: 3, postalCode: '86000', city: 'Poitiers' }))
            .toEqual({ id: 3, country: 'France', postalCode: '86000', city: 'Poitiers', street: null, streetComplement: null })
    })

    it('mapContactToDraft : hasSecondaryPhone vrai seulement si 2e numéro présent', () => {
        const one = mapContactToDraft({ '@id': '/api/carrier_contacts/1', id: 1, firstName: 'Jean', phonePrimary: '0102030405' })
        expect(one.hasSecondaryPhone).toBe(false)
        expect(one.firstName).toBe('Jean')

        const two = mapContactToDraft({ '@id': '/api/carrier_contacts/2', id: 2, phonePrimary: '0102030405', phoneSecondary: '0605040302' })
        expect(two.hasSecondaryPhone).toBe(true)
        expect(two.phoneSecondary).toBeTruthy()
    })

    it('mapPriceToDraft : direction + IRIs des relations de branche', () => {
        const draft = mapPriceToDraft({
            '@id': '/api/carrier_prices/5',
            id: 5,
            direction: 'CLIENT',
            client: { '@id': '/api/clients/3' },
            clientDeliveryAddress: { '@id': '/api/client_addresses/8' },
            departureSite: '/api/sites/1',
            containerType: 'BENNE',
            pricingUnit: 'FORFAIT',
            price: '120.00',
            priceState: 'EN_COURS',
        })
        expect(draft).toMatchObject({
            id: 5,
            direction: 'CLIENT',
            clientIri: '/api/clients/3',
            clientDeliveryAddressIri: '/api/client_addresses/8',
            departureSiteIri: '/api/sites/1',
            supplierIri: null,
            containerType: 'BENNE',
            pricingUnit: 'FORFAIT',
            price: '120.00',
            priceState: 'EN_COURS',
        })
    })

    it('visibilité des boutons selon la permission', () => {
        const can = (granted: string[]) => (code: string) => granted.includes(code)

        // Modifier : seulement avec manage.
        expect(canEditCarrier(can(['transport.carriers.manage']))).toBe(true)
        expect(canEditCarrier(can(['transport.carriers.view']))).toBe(false)

        // Archiver : permission archive ET actif ; Restaurer : archive ET archivé.
        const withArchive = can(['transport.carriers.archive'])
        const noArchive = can(['transport.carriers.manage'])
        expect(showArchiveAction(withArchive, false)).toBe(true)
        expect(showArchiveAction(withArchive, true)).toBe(false)
        expect(showRestoreAction(withArchive, true)).toBe(true)
        expect(showRestoreAction(withArchive, false)).toBe(false)
        expect(showArchiveAction(noArchive, false)).toBe(false)
        expect(showRestoreAction(noArchive, true)).toBe(false)
    })
})
