/**
 * useCep.spec.js — V#9 (composable extraído)
 */
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';

const fetchMock = vi.fn();
globalThis.fetch = fetchMock;

const { useCep } = await import('../useCep.js');

beforeEach(() => fetchMock.mockReset());
afterEach(() => fetchMock.mockReset());

describe('useCep — busca ViaCEP', () => {
    it('retorna null se CEP tem menos de 8 dígitos (no-op)', async () => {
        const { fetchCep } = useCep();
        expect(await fetchCep('123')).toBe(null);
        expect(await fetchCep('')).toBe(null);
        expect(await fetchCep(null)).toBe(null);
        expect(fetchMock).not.toHaveBeenCalled();
    });

    it('aceita CEP com máscara (digitsOnly normaliza)', async () => {
        fetchMock.mockResolvedValue({ ok: true, json: async () => ({ localidade: 'São Paulo', uf: 'SP', logradouro: 'Av Paulista', bairro: 'Bela Vista', complemento: '' }) });
        const { fetchCep } = useCep();
        const r = await fetchCep('01310-100');
        expect(r).toEqual({
            cidade: 'São Paulo',
            uf: 'SP',
            bairro: 'Bela Vista',
            endereco: 'Av Paulista',
            complemento: ''
        });
        expect(fetchMock).toHaveBeenCalledWith('https://viacep.com.br/ws/01310100/json/');
    });

    it('retorna null se ViaCEP devolve {erro: true}', async () => {
        fetchMock.mockResolvedValue({ ok: true, json: async () => ({ erro: true }) });
        const { fetchCep } = useCep();
        expect(await fetchCep('00000000')).toBe(null);
    });

    it('retorna null se HTTP falha (sem propagar erro)', async () => {
        fetchMock.mockResolvedValue({ ok: false, status: 500 });
        const { fetchCep, error } = useCep();
        expect(await fetchCep('01310100')).toBe(null);
        expect(error.value).toContain('500');
    });

    it('captura exception de rede como null', async () => {
        fetchMock.mockRejectedValue(new Error('network'));
        const { fetchCep, error } = useCep();
        expect(await fetchCep('01310100')).toBe(null);
        expect(error.value).toBe('network');
    });

    it('loading reflete o ciclo da request', async () => {
        let resolveIt;
        fetchMock.mockReturnValue(new Promise((res) => { resolveIt = res; }));
        const { fetchCep, loading } = useCep();
        const p = fetchCep('01310100');
        expect(loading.value).toBe(true);
        resolveIt({ ok: true, json: async () => ({ localidade: 'A', uf: 'B' }) });
        await p;
        expect(loading.value).toBe(false);
    });
});
