import { describe, it, expect, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import { defineComponent, h, ref, computed } from 'vue'
import { emptyAddress } from '~/modules/commercial/types/clientForm'
import ClientAddressBlock from '../ClientAddressBlock.vue'

// Le composable BAN est mocke : aucun appel reseau, aucune suggestion chargee.
// On reproduit ainsi l'etat « adresse persistee, mais liste de suggestions
// vide » (remontage apres validation / edition d'une adresse existante).
vi.mock('~/shared/composables/useAddressAutocomplete', () => ({
    useAddressAutocomplete: () => ({
        searchCity: vi.fn(),
        searchAddress: vi.fn(),
    }),
}))

// Auto-imports Nuxt/Vue utilises sans import explicite par le composant.
vi.stubGlobal('useI18n', () => ({ t: (key: string) => key }))
vi.stubGlobal('ref', ref)
vi.stubGlobal('computed', computed)

// Stub de MalioInputAutocomplete : expose les `value` des options recues, pour
// verifier que la rue courante figure bien dans la liste (sinon le composant
// Malio ne peut pas resoudre/afficher la valeur liee -> champ vide).
const MalioInputAutocompleteStub = defineComponent({
    name: 'MalioInputAutocomplete',
    props: {
        modelValue: { type: [String, Number, null], default: undefined },
        options: { type: Array as () => { value: string | number, label: string }[], default: () => [] },
        loading: { type: Boolean, default: false },
        minSearchLength: { type: Number, default: 0 },
        label: { type: String, default: '' },
        readonly: { type: Boolean, default: false },
    },
    emits: ['update:modelValue', 'search', 'select'],
    setup(props) {
        return () => h('div', {
            'data-testid': 'addr-autocomplete',
            'data-options': JSON.stringify(props.options.map(o => o.value)),
        })
    },
})

function mountBlock(street: string | null) {
    return mount(ClientAddressBlock, {
        props: {
            modelValue: { ...emptyAddress(), street },
            title: 'Adresse',
            categoryOptions: [],
            siteOptions: [],
            contactOptions: [],
            countryOptions: [],
        },
        global: {
            stubs: {
                MalioButtonIcon: true,
                MalioCheckbox: true,
                MalioSelect: true,
                MalioSelectCheckbox: true,
                MalioInputText: true,
                MalioInputAutocomplete: MalioInputAutocompleteStub,
            },
        },
    })
}

describe('ClientAddressBlock — affichage de l\'adresse persistee', () => {
    it('inclut la rue courante dans les options de l\'autocomplete meme sans recherche BAN', () => {
        const wrapper = mountBlock('8 Boulevard du Port')

        const el = wrapper.find('[data-testid="addr-autocomplete"]')
        const values = JSON.parse(el.attributes('data-options') ?? '[]')

        expect(values).toContain('8 Boulevard du Port')
    })
})

/**
 * Stub MalioInputText qui re-expose `label` + `error` recus : permet de cibler
 * un champ par son libelle et de verifier l'erreur 422 propagee (ERP-101).
 */
const MalioInputTextProbe = defineComponent({
    name: 'MalioInputTextProbe',
    props: {
        modelValue: { type: [String, Number, null], default: undefined },
        error: { type: String, default: '' },
        label: { type: String, default: '' },
        readonly: { type: Boolean, default: false },
    },
    setup(props) {
        return () => h('div', {
            'data-testid': 'addr-text',
            'data-label': props.label,
            'data-error': props.error,
        })
    },
})

describe('ClientAddressBlock — mapping erreur par champ (ERP-101)', () => {
    function mountWithErrors(errors: Record<string, string>) {
        return mount(ClientAddressBlock, {
            props: {
                modelValue: emptyAddress(),
                title: 'Adresse',
                categoryOptions: [],
                siteOptions: [],
                contactOptions: [],
                countryOptions: [],
                errors,
            },
            global: {
                stubs: {
                    MalioButtonIcon: true,
                    MalioCheckbox: true,
                    MalioSelect: true,
                    MalioSelectCheckbox: true,
                    MalioInputAutocomplete: MalioInputAutocompleteStub,
                    MalioInputText: MalioInputTextProbe,
                },
            },
        })
    }

    it('affiche l\'erreur serveur sur le champ code postal via la prop errors', () => {
        const wrapper = mountWithErrors({ postalCode: 'Code postal invalide.' })

        const field = wrapper.findAll('[data-testid="addr-text"]').find(
            el => el.attributes('data-label') === 'commercial.clients.form.address.postalCode',
        )
        expect(field?.attributes('data-error')).toBe('Code postal invalide.')
    })
})
