const schema = require('./data/eds-c-navigation.schema.json');
const exampleJson = require('./data/eds-c-navigation.example.json');
const fs = require('node:fs');
const path = require('node:path');
const Ajv = require('ajv');
const ajv = new Ajv();

const handlebars = require('handlebars');
const { validateSchema } = require('../../development/tests/validate-schema.js');
const dataAttributesSchema = require('../eds-c-data-attributes/data/eds-c-data-attributes.schema.json');


const { findTemplates } = require('../../development/tests/templateLoader.js');
findTemplates(['eds-c-navigation', 'eds-c-accordion', 'eds-c-data-attributes']).load(handlebars);


const componentTemplate = '{{> eds-c-navigation}}';
const componentExpanderTemplate = '{{> eds-c-navigation-expander}}';
const componentHbs = handlebars.compile(componentTemplate);
const componentExpanderHbs = handlebars.compile(componentExpanderTemplate);
const renderedComponent = componentHbs(exampleJson);
const expanderRenderedComponent = componentExpanderHbs(exampleJson);

describe('EDS Component', () => {
	test('docs file exists', () => {
		const exists = fs.existsSync(path.resolve(__dirname, 'docs.md'));
		expect(exists).toBe(true);
	});
});


describe('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 valid = validateSchema(schema, exampleJson, [
			{ name: 'eds-c-data-attributes', schema: dataAttributesSchema }
		]);
		expect(valid).toBeTruthy();
	});

	test('Should have  eds-c-navigation--tray-dropdown css class rendered', () => {
		document.body.innerHTML = renderedComponent;
		const container = document.querySelector('.eds-c-navigation');
		expect(container).not.toBeNull();
		expect(
			container.classList.contains('eds-c-navigation--tray-dropdown')
		).toBeTruthy();
		expect(container.getAttribute('aria-label')).toBe(
			'example-nav-with-tray-dropdown'
		);
	});

	test("Shouldn't have  eds-c-navigation--tray-dropdown css class rendered", () => {
		const { trayDropdown, ...testData } = exampleJson;
		document.body.innerHTML = componentHbs(testData);
		const container = document.querySelector('.eds-c-navigation');
		expect(container).not.toBeNull();
		expect(
			container.classList.contains('eds-c-navigation--fixed-width-dropdown')
		).toBeTruthy();
	});

	test('Should render desktop menu', () => {
		document.body.innerHTML = renderedComponent;
		const desktopMenuElement = document.querySelector(
			'.eds-c-navigation__desktop-menu'
		);
		const desktopMenuItems = desktopMenuElement.querySelectorAll('li');
		expect(desktopMenuElement).not.toBeNull();
		expect([...desktopMenuItems].length).toBe(4);
	});

	test('Should render desktop menu noDropdown link', () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					triggerText: 'Publish with us',
					triggerUrl: 'https://dev-skills-url1.com',
					noDropdown: true,
					dataAttributes: [
						{
							name: 'track',
							value: 'click-publish-with-us'
						}
					]
				}
			]
		};

		document.body.innerHTML = componentHbs(testData);

		const linkElement = document.querySelector(
			'.eds-c-navigation__desktop-menu .eds-c-navigation__menu-item a'
		);

		expect(linkElement).not.toBeNull();
		expect(linkElement.getAttribute('href')).toBe(
			'https://dev-skills-url1.com'
		);
		expect(linkElement.getAttribute('data-track')).toEqual(
			'click-publish-with-us'
		);
		expect(
			linkElement.hasAttribute('data-eds-c-navigation-expander')
		).toBeFalsy();
		expect(
			linkElement.classList.contains('eds-c-navigation__menu-link--active')
		).toBeFalsy();
		expect(linkElement.textContent.replace(/\s+/g, ' ').trim()).toBe(
			'Publish with us'
		);
	});

	test("Shouldn't desktop menu render icon", () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					triggerText: 'Publish with us',
					triggerUrl: 'https://dev-skills-url1.com',
					noDropdown: true,
					dataAttributes: [
						{
							name: 'track',
							value: 'click-publish-with-us'
						}
					]
				}
			]
		};

		document.body.innerHTML = componentHbs(testData);

		const icon = document.querySelector(
			'.eds-c-navigation__desktop-menu .eds-c-navigation__menu-item a .eds-c-navigation__icon'
		);

		expect(icon).toBeNull();
	});

	test('Should render desktop menu active link', () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					active: true,
					triggerText: 'Publish with us',
					triggerUrl: 'https://dev-skills-url1.com',
					noDropdown: true,
					dataAttributes: [
						{
							name: 'track',
							value: 'click-publish-with-us'
						}
					]
				}
			]
		};

		document.body.innerHTML = componentHbs(testData);

		const linkElement = document.querySelector(
			'.eds-c-navigation__desktop-menu .eds-c-navigation__menu-item .eds-c-navigation__menu-link--active'
		);

		expect(linkElement).not.toBeNull();
	});

	test('Should render desktop menu link', () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					triggerText: 'Publish with us',
					triggerUrl: 'find-and-explore',
					dataAttributes: [
						{
							name: 'track',
							value: 'click-publish-with-us'
						}
					]
				}
			]
		};

		document.body.innerHTML = componentHbs(testData);

		const linkElement = document.querySelector(
			'.eds-c-navigation__desktop-menu .eds-c-navigation__menu-item a'
		);

		expect(linkElement).not.toBeNull();
		expect(linkElement.getAttribute('href')).toBe('#find-and-explore');
		expect(linkElement.getAttribute('data-track')).toEqual(
			'click-publish-with-us'
		);
		expect(
			linkElement.hasAttribute('data-eds-c-navigation-expander')
		).toBeTruthy();
		expect(
			linkElement.classList.contains('eds-c-navigation__menu-link--active')
		).toBeFalsy();
		expect(linkElement.textContent.replace(/\s+/g, ' ').trim()).toBe(
			'Publish with us'
		);
	});

	test('Should render icon', () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					triggerText: 'Publish with us',
					triggerUrl: 'find-and-explore',
					dataAttributes: [
						{
							name: 'track',
							value: 'click-publish-with-us'
						}
					]
				}
			]
		};

		document.body.innerHTML = componentHbs(testData);

		const icon = document.querySelector(
			'.eds-c-navigation__desktop-menu .eds-c-navigation__menu-item a .eds-c-navigation__icon'
		);
		const xlinkHref = icon.querySelector('use').getAttribute('xlink:href');
		expect(icon).not.toBeNull();
		expect(xlinkHref).toBe(
			'#eds-i-chevron-down-small'
		);
	});

	test('Should render mobile menu', () => {
		document.body.innerHTML = renderedComponent;
		const mobileMenuElement = document.querySelector(
			'.eds-c-navigation__mobile-menu'
		);
		const mobileMenuItems = mobileMenuElement.querySelectorAll('li');
		expect(mobileMenuElement).not.toBeNull();
		expect([...mobileMenuItems].length).toBe(20);
	});

	test('Should render mobile menu noDropdown link', () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					triggerText: 'Publish with us',
					triggerUrl: 'https://dev-skills-url1.com',
					noDropdown: true,
					dataAttributes: [
						{
							name: 'track',
							value: 'click-publish-with-us'
						}
					]
				}
			]
		};

		document.body.innerHTML = componentHbs(testData);

		const listElement = document.querySelector(
			'.eds-c-navigation__mobile-menu li'
		);

		const linkElement = document.querySelector(
			'.eds-c-navigation__mobile-menu li a'
		);

		expect(linkElement.getAttribute('href')).toBe(
			'https://dev-skills-url1.com'
		);
		expect(linkElement.getAttribute('data-track')).toEqual(
			'click-publish-with-us'
		);
		expect(
			linkElement.hasAttribute('data-eds-c-navigation-expander')
		).toBeFalsy();
		expect(
			linkElement.classList.contains('eds-c-navigation__menu-link--active')
		).toBeFalsy();
		expect(linkElement.textContent.replace(/\s+/g, ' ').trim()).toBe(
			'Publish with us'
		);
		expect(
			listElement.classList.contains('eds-c-navigation__no-dropdown')
		).toBeTruthy();
	});

	test("Shouldn't mobile menu render icon", () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					triggerText: 'Publish with us',
					triggerUrl: 'https://dev-skills-url1.com',
					noDropdown: true,
					dataAttributes: [
						{
							name: 'track',
							value: 'click-publish-with-us'
						}
					]
				}
			]
		};

		document.body.innerHTML = componentHbs(testData);

		const icon = document.querySelector(
			'.eds-c-navigation__mobile-menu .eds-c-navigation__menu-item a .eds-c-navigation__icon'
		);

		expect(icon).toBeNull();
	});

	// test('Should render mobile menu active link', () => {
	// 	const testData = {
	// 		...exampleJson,
	// 		navigationItems: [
	// 			{
	// 				active: true,
	// 				triggerText: 'Publish with us',
	// 				triggerUrl: 'https://dev-skills-url1.com',
	// 				dataAttributes: [
	// 					{
	// 						name: 'track',
	// 						value: 'click-publish-with-us'
	// 					}
	// 				]
	// 			}
	// 		]
	// 	};
	//
	// 	document.body.innerHTML = componentHbs(testData);
	//
	// 	const linkElement = document.querySelector(
	// 		'.eds-c-navigation__mobile-menu li .eds-c-navigation__menu-link--active'
	// 	);
	//
	// 	expect(linkElement).not.toBeNull();
	// });

	test('Should render accordion', () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					triggerText: 'Find and explore',
					triggerUrl: 'find-and-explore',
					noDropdown: false,
					dataAttributes: [
						{
							name: 'track',
							value: 'click-find-and-explore'
						}
					],
					mobileAccordion: {
						open: false,
						id: 'find-and-explore-mobile-1',
						groupedContent: false,
						iconURL:
							'#eds-i-chevron-down-small',
						headingLevel: '3',
						title: 'Find and explore',
						content:
							'<h4>Find</h4><ul><li><a href="">Find a journal</a><li><a href="">Find a book</a></ul><h4>Explore</h4><ul><li><a href="">Article collections</a><li><a href="">Communities</a></ul>',
						dataAttributes: [
							{
								name: 'track',
								value: 'click-find-and-explore'
							}
						]
					}
				}
			]
		};

		document.body.innerHTML = componentHbs(testData);

		const accordion = document.querySelector(
			'.eds-c-navigation__mobile-menu .eds-c-accordion'
		);
		expect(accordion).toBeTruthy();
	});

	test('Should have lists in expander menu', () => {
		document.body.innerHTML = expanderRenderedComponent;
		const container = document.querySelector(
			'.eds-c-navigation__expander-enhanced-but-no-js'
		);
		const itemsElement = container.querySelectorAll(
			'.eds-c-navigation__menu>li'
		);

		expect(container).not.toBeNull();
		expect(container.getAttribute('aria-label')).toBe('example-nav-expander-with-tray-dropdown');
		expect([...itemsElement].length).toBe(4);
	});

	test('Should have lists in expander menu', () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					triggerText: 'Find and explore',
					triggerUrl: 'find-and-explore',
					noDropdown: false,
					dataAttributes: [
						{
							name: 'track',
							value: 'click-find-and-explore'
						}
					],
					groups: [
						{
							heading: 'Find',
							links: [
								{
									linkText: 'Find a journal',
									linkUrl: 'https://some-find-a-journal-url.com',
									dataAttributes: [
										{
											name: 'track',
											value: 'click-find-a-journal'
										}
									]
								},
								{
									linkText: 'Find a book',
									linkUrl: 'https://some-find-a-book-url.com',
									dataAttributes: [
										{
											name: 'track',
											value: 'click-find-a-book'
										}
									]
								}
							]
						},
						{
							heading: 'Explore',
							links: [
								{
									linkText: 'Article collections',
									linkUrl: 'https://some-article-collections-url.com',
									dataAttributes: [
										{
											name: 'track',
											value: 'click-article-collections'
										}
									]
								},
								{
									linkText: 'Communities',
									linkUrl: 'https://some-communities-url.com',
									dataAttributes: [
										{
											name: 'track',
											value: 'click-communities'
										}
									]
								}
							]
						}
					]
				}
			]
		};

		document.body.innerHTML = componentExpanderHbs(testData);

		const navigationMenuElement = document.querySelector(
			'.eds-c-navigation__menu'
		);

		const navigationTitleMenuElement = navigationMenuElement.querySelector(
			'h3'
		);

		const navigationDropdownElement = navigationMenuElement.querySelector(
			'.eds-c-navigation__dropdown'
		);


		expect(navigationTitleMenuElement).not.toBeNull();
		expect(navigationTitleMenuElement).not.toBeNull();
		expect(navigationTitleMenuElement.textContent.replace(/\s+/g, ' ').trim()).toBe('Find and explore');
		expect(navigationDropdownElement).not.toBeNull();
		expect(navigationDropdownElement.getAttribute('aria-label')).toBe(
			'Find and explore'
		);
		expect(navigationDropdownElement.getAttribute('id')).toBe(
			'find-and-explore'
		);
	});

	test('Should have eds-c-navigation__heading element', () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					triggerText: 'Find and explore',
					triggerUrl: 'find-and-explore',
					noDropdown: false,
					dataAttributes: [
						{
							name: 'track',
							value: 'click-find-and-explore'
						}
					],
					groups: [
						{
							heading: 'Find',
							links: [
								{
									linkText: 'Find a journal',
									linkUrl: 'https://some-find-a-journal-url.com',
									dataAttributes: [
										{
											name: 'track',
											value: 'click-find-a-journal'
										}
									]
								},
								{
									linkText: 'Find a book',
									linkUrl: 'https://some-find-a-book-url.com',
									dataAttributes: [
										{
											name: 'track',
											value: 'click-find-a-book'
										}
									]
								}
							]
						}
					]
				}
			]
		};

		document.body.innerHTML = componentExpanderHbs(testData);

		const navigationMenuElement = document.querySelector(
			'.eds-c-navigation__dropdown-group'
		);

		const navigationHeadingElement = navigationMenuElement.querySelector(
			'.eds-c-navigation__heading'
		);


		expect(navigationHeadingElement).not.toBeNull();
		expect(navigationHeadingElement.textContent.replace(/\s+/g, ' ').trim()).toBe('Find');
	});

	test('Should have eds-c-navigation__list element', () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					triggerText: 'Find and explore',
					triggerUrl: 'find-and-explore',
					noDropdown: false,
					dataAttributes: [
						{
							name: 'track',
							value: 'click-find-and-explore'
						}
					],
					groups: [
						{
							heading: 'Find',
							links: [
								{
									linkText: 'Find a journal',
									linkUrl: 'https://some-find-a-journal-url.com',
									dataAttributes: [
										{
											name: 'track',
											value: 'click-find-a-journal'
										}
									]
								},
								{
									linkText: 'Find a book',
									linkUrl: 'https://some-find-a-book-url.com',
									dataAttributes: [
										{
											name: 'track',
											value: 'click-find-a-book'
										}
									]
								}
							]
						}
					]
				}
			]
		};

		document.body.innerHTML = componentExpanderHbs(testData);

		const navigationMenuElement = document.querySelector(
			'.eds-c-navigation__dropdown-group'
		);

		const navigationListElement = navigationMenuElement.querySelector(
			'.eds-c-navigation__list'
		);


		expect(navigationListElement).not.toBeNull();
		expect([...navigationListElement.querySelectorAll('.eds-c-navigation__list-item')].length).toBe(2);
	});

	test('Should render link correctly', () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					triggerText: 'Find and explore',
					triggerUrl: 'find-and-explore',
					noDropdown: false,
					dataAttributes: [
						{
							name: 'track',
							value: 'click-find-and-explore'
						}
					],
					groups: [
						{
							heading: 'Find',
							links: [
								{
									linkText: 'Find a journal',
									linkUrl: 'https://some-find-a-journal-url.com',
									dataAttributes: [
										{
											name: 'track',
											value: 'click-find-a-journal'
										}
									]
								}
							]
						}
					]
				}
			]
		};

		document.body.innerHTML = componentExpanderHbs(testData);
		console.log(componentExpanderHbs(testData))

		const navigationMenuElement = document.querySelector(
			'.eds-c-navigation__dropdown-group'
		);

		const navigationLinkElement = navigationMenuElement.querySelector(
			'.eds-c-navigation__list-link'
		);


		expect(navigationLinkElement).not.toBeNull();
		expect(navigationLinkElement.textContent.replace(/\s+/g, ' ').trim()).toBe('Find a journal');
		expect(navigationLinkElement.getAttribute('href')).toBe(
			'https://some-find-a-journal-url.com'
		);
		expect(navigationLinkElement.getAttribute('data-track')).toEqual(
			'click-find-a-journal'
		);

	});

	test('Should have links rendered', () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					"triggerText": "Develop your skills",
					"triggerUrl": "develop-your-skills",
					"noDropdown": false,
					"links": [
						{
							"linkText": "Develop your skills link 1",
							"linkUrl": "https://dev-skills-url1.com",
							"dataAttributes": [
								{
									"name": "test",
									"value": "dev-skills-test1"
								}
							]
						},
						{
							"linkText": "Develop your skills link 2",
							"linkUrl": "https://dev-skills-url2.com",
							"dataAttributes": [
								{
									"name": "test",
									"value": "dev-skills-test2"
								}
							]
						},
						{
							"linkText": "Develop your skills link 3",
							"linkUrl": "https://dev-skills-url3.com",
							"dataAttributes": [
								{
									"name": "test",
									"value": "dev-skills-test3"
								}
							]
						},
						{
							"linkText": "Develop your skills link 4",
							"linkUrl": "https://dev-skills-url4.com",
							"dataAttributes": [
								{
									"name": "test",
									"value": "dev-skills-test4"
								}
							]
						}
					]
				}
			]
		};

		document.body.innerHTML = componentExpanderHbs(testData);

		const navigationListElement = document.querySelector(
			'.eds-c-navigation__list'
		);

		const navigationListItemsElement = navigationListElement.querySelectorAll(
			'.eds-c-navigation__list-item'
		);


		expect(navigationListElement).not.toBeNull();
		expect(navigationListItemsElement).not.toBeNull();
		expect([...navigationListItemsElement].length).toBe(4);
	});

	test('Should render links link correctly', () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					"triggerText": "Develop your skills",
					"triggerUrl": "develop-your-skills",
					"noDropdown": false,
					"links": [
						{
							"linkText": "Develop your skills link 1",
							"linkUrl": "https://dev-skills-url1.com",
							"dataAttributes": [
								{
									"name": "test",
									"value": "dev-skills-test1"
								}
							]
						}
					]
				}
			]
		};

		document.body.innerHTML = componentExpanderHbs(testData);

		const navigationListElement = document.querySelector(
			'.eds-c-navigation__list'
		);

		const navigationLinkElement = navigationListElement.querySelector(
			'.eds-c-navigation__list-link'
		);

		expect(navigationLinkElement.textContent.replace(/\s+/g, ' ').trim()).toBe('Develop your skills link 1');
		expect(navigationLinkElement.getAttribute('href')).toBe(
			'https://dev-skills-url1.com'
		);
		expect(navigationLinkElement.getAttribute('data-test')).toEqual(
			'dev-skills-test1'
		);
	});

	test('Should render noDropdown links link correctly', () => {
		const testData = {
			...exampleJson,
			navigationItems: [
				{
					"triggerText": "Develop your skills",
					"triggerUrl": "develop-your-skills",
					"noDropdown": true,
					"links": [
						{
							"linkText": "Develop your skills link 1",
							"linkUrl": "https://dev-skills-url1.com",
							"dataAttributes": [
								{
									"name": "test",
									"value": "dev-skills-test1"
								}
							]
						}
					]
				}
			]
		};

		document.body.innerHTML = componentExpanderHbs(testData);

		const navigationListElement = document.querySelector(
			'.eds-c-navigation__list'
		);

		const navigationLinkElement = navigationListElement.querySelector(
			'.eds-c-navigation__list-link'
		);

		expect(navigationLinkElement.textContent.replace(/\s+/g, ' ').trim()).toBe('Develop your skills');
		expect(navigationLinkElement.getAttribute('href')).toBe(
			'develop-your-skills'
		);
	});

	test('Should render trayDropdown false part', () => {
		const { trayDropdown, ...testData } = exampleJson;

		document.body.innerHTML = componentExpanderHbs(testData);

		const navigationMenuElement = document.querySelector(
			'.eds-c-navigation__menu'
		);

		const navigationTitleMenuElement = navigationMenuElement.querySelector(
			'h3'
		);

		const navigationDropdownElement = navigationMenuElement.querySelector(
			'.eds-c-navigation__dropdown'
		);

		expect(navigationTitleMenuElement).not.toBeNull();
		expect(navigationTitleMenuElement).not.toBeNull();
		expect(navigationTitleMenuElement.textContent.replace(/\s+/g, ' ').trim()).toBe('Find and explore');
		expect(navigationDropdownElement).not.toBeNull();
		expect(navigationDropdownElement.getAttribute('aria-label')).toBe(
			'Find and explore'
		);
		expect(navigationDropdownElement.getAttribute('id')).toBe(
			'find-and-explore'
		);
	});

	test('Should render trayDropdown false links link correctly', () => {
		const { trayDropdown, ...testData } = exampleJson;
		const newTestData = {
			...testData,
			"iconPathSecondary": "#eds-i-chevron-right-small",
			navigationItems: [
				{
					"triggerText": "Develop your skills",
					"triggerUrl": "develop-your-skills",
					"links": [
						{
							"linkText": "Develop your skills link 1",
							"linkUrl": "https://dev-skills-url1.com",
							"noDropdown": false,
							"dataAttributes": [
								{
									"name": "test",
									"value": "dev-skills-test1"
								}
							]
						}
					]
				}
			]
		};

		document.body.innerHTML = componentExpanderHbs(newTestData);

		const navigationListElement = document.querySelector(
			'.eds-c-navigation__list'
		);

		const navigationLinkElement = navigationListElement.querySelector(
			'.eds-c-navigation__list-link'
		);

		const icon = document.querySelector('.eds-c-navigation__link-icon');
		const xlinkHref = icon.querySelector('use').getAttribute('xlink:href');
		expect(icon).not.toBeNull();
		expect(xlinkHref).toBe('#eds-i-chevron-right-small');

		expect(navigationLinkElement.textContent.replace(/\s+/g, ' ').trim()).toBe('Develop your skills link 1');
		expect(navigationLinkElement.getAttribute('href')).toBe(
			'https://dev-skills-url1.com'
		);
		expect(navigationLinkElement.getAttribute('data-test')).toEqual(
			'dev-skills-test1'
		);
	});

	test('Template passes basic HTML accessibility', async () => {
		expect(await axe(renderedComponent)).toHaveNoViolations();
	});
});