import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
// @vitest-environment happy-dom
import { useState } from 'react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
/**
 * TagInput — chip editor with autocomplete from the collection's in-use
 * vocabulary (`GET /collections/:slug/field-values`). Pins the dedupe
 * contract: adding "ai" when "AI" already exists in the collection resolves
 * to the canonical "AI", and tags already on the post are never duplicated.
 */
let fieldValues = [];
const cmsApi = vi.fn(async (endpoint, _options) => {
    if (endpoint.startsWith('/collections/posts/field-values')) {
        return { data: { field: 'tags', values: fieldValues }, status: 200 };
    }
    return { data: {}, status: 200 };
});
vi.mock('../../lib/api.js', () => ({
    cmsApi: (e, o) => cmsApi(e, o),
    ensureCsrfToken: vi.fn(async () => { }),
}));
const { TagInput } = await import('../../components/TagInput.js');
function Harness({ initial = [], maxTags }) {
    const [tags, setTags] = useState(initial);
    return (_jsxs("div", { children: [_jsx(TagInput, { id: "tags", value: tags, onChange: setTags, collection: "posts", maxTags: maxTags }), _jsx("output", { "data-testid": "value", children: JSON.stringify(tags) })] }));
}
function currentValue() {
    return JSON.parse(screen.getByTestId('value').textContent ?? '[]');
}
beforeEach(() => {
    cmsApi.mockClear();
    fieldValues = [];
});
describe('TagInput', () => {
    it('adds a tag on Enter and clears the draft', () => {
        render(_jsx(Harness, {}));
        const input = screen.getByRole('combobox');
        fireEvent.change(input, { target: { value: 'Design' } });
        fireEvent.keyDown(input, { key: 'Enter' });
        expect(currentValue()).toEqual(['Design']);
        expect(input.value).toBe('');
    });
    it('dedupes case-insensitively against tags already on the post', () => {
        render(_jsx(Harness, { initial: ['AI'] }));
        const input = screen.getByRole('combobox');
        fireEvent.change(input, { target: { value: 'ai' } });
        fireEvent.keyDown(input, { key: 'Enter' });
        expect(currentValue()).toEqual(['AI']);
    });
    it('resolves new tags to the canonical casing already used in the collection', async () => {
        fieldValues = [{ value: 'AI', count: 7 }];
        render(_jsx(Harness, {}));
        const input = screen.getByRole('combobox');
        fireEvent.focus(input);
        await waitFor(() => expect(cmsApi).toHaveBeenCalled());
        fireEvent.change(input, { target: { value: 'ai' } });
        fireEvent.keyDown(input, { key: 'Enter' });
        expect(currentValue()).toEqual(['AI']);
    });
    it('shows suggestions on focus and adds one on click', async () => {
        fieldValues = [
            { value: 'Design', count: 3 },
            { value: 'DevOps', count: 1 },
        ];
        render(_jsx(Harness, {}));
        fireEvent.focus(screen.getByRole('combobox'));
        const option = await screen.findByText('Design');
        fireEvent.click(option);
        expect(currentValue()).toEqual(['Design']);
        // An added tag drops out of the suggestion list.
        expect(screen.queryByRole('option', { name: 'Design' })).toBeNull();
    });
    it('removes a tag via its remove button and the last tag via Backspace', () => {
        render(_jsx(Harness, { initial: ['One', 'Two'] }));
        fireEvent.click(screen.getByRole('button', { name: 'Remove tag One' }));
        expect(currentValue()).toEqual(['Two']);
        fireEvent.keyDown(screen.getByRole('combobox'), { key: 'Backspace' });
        expect(currentValue()).toEqual([]);
    });
    it('disables input at the maxTags cap', () => {
        render(_jsx(Harness, { initial: ['a', 'b'], maxTags: 2 }));
        expect(screen.getByRole('combobox').disabled).toBe(true);
    });
});
//# sourceMappingURL=tag-input.render.test.js.map