const schema = require('./data/eds-c-label.schema.json');
const exampleJson = require('./data/eds-c-label.example.json');
const Ajv = require('ajv');
const ajv = new Ajv();
const handlebars = require('handlebars');

const {findTemplates} = require('../../development/tests/templateLoader.js');
findTemplates(['eds-c-label']).load(handlebars);

const componentTemplate = '{{> eds-c-label}}';

const componentHbs = handlebars.compile(componentTemplate);
const renderedComponent = componentHbs(exampleJson);

describe('Label Schema Validation and Accessibility Test', () => {
    const { configureAxe, toHaveNoViolations } = require('jest-axe');
    expect.extend(toHaveNoViolations);
    
    const axe = configureAxe({
        rules: {
            region: { enabled: false }
        }
    });
    
    test('Example data matches schema', () => {
        const validate = ajv.compile(schema);
        const valid = validate(exampleJson);
    
        if (!valid) {
            // Extract and format the Ajv validation errors
            const errors = validate.errors.map((error) => ajv.errorsText([error])).join('\n');
            throw new Error(errors);
        }
    
        expect(valid).toBeTruthy();
    });
    
    test('Should render label', () => {
        const testData = { ...exampleJson, inputId: 'input-id' };
        document.body.innerHTML = componentHbs(testData);
        const container = document.querySelector('.eds-c-label');
        expect(container).not.toBeNull();
        expect(container.getAttribute('for')).toBe('input-id');
        expect(container.textContent.replace(/\s+/g, ' ').trim()).toBe('Label optional suffix');
    });

    test('Should render cssClass attribute', () => {
        const testData = { ...exampleJson, cssClass: 'custom-label-css-class' };
        document.body.innerHTML = componentHbs(testData);

        const labelElement = document.querySelector('.eds-c-label');
        expect(labelElement.classList.contains('custom-label-css-class')).toBeTruthy();
    });

    test('Should render hideLabel css classes', () => {
        const testData = { ...exampleJson, hideLabel: true };
        document.body.innerHTML = componentHbs(testData);

        const labelElement = document.querySelector('.eds-c-label');
        expect(labelElement.classList.contains('u-visually-hidden')).toBeTruthy();
    });

    test('Should render required text', () => {
        const testData = { ...exampleJson, required: true };
        document.body.innerHTML = componentHbs(testData);

        const labelElement = document.querySelector('.eds-c-label');
        expect(labelElement.textContent.replace(/\s+/g, ' ').trim()).toBe('Label required');
    });

    test('Should render required text', () => {
        const testData = { ...exampleJson, optionalSuffix: false };
        document.body.innerHTML = componentHbs(testData);

        const labelElement = document.querySelector('.eds-c-label');
        expect(labelElement.textContent.replace(/\s+/g, ' ').trim()).toBe('Label (optional)');
    });
    
    test('Template passes basic HTML accessibility', async () => {
        expect(await axe(renderedComponent)).toHaveNoViolations();
    });
});