'use strict';

const assert = require('assert');
const fs = require('fs');
const path = require('path');

function read(relativePath) {
	const filePath = path.join(__dirname, '..', relativePath);
	assert(fs.existsSync(filePath), `${relativePath} should exist`);
	return fs.readFileSync(filePath, 'utf8');
}

function assertMissing(relativePath, message) {
	const filePath = path.join(__dirname, '..', relativePath);
	assert(!fs.existsSync(filePath), message || `${relativePath} should not exist`);
}

function assertIncludes(haystack, needle, message) {
	assert(
		haystack.includes(needle),
		message || `Expected file to include ${needle}`
	);
}

function assertExcludes(haystack, needle, message) {
	assert(
		!haystack.includes(needle),
		message || `Expected file not to include ${needle}`
	);
}

function assertMatches(haystack, pattern, message) {
	assert(
		pattern.test(haystack),
		message || `Expected file to match ${pattern}`
	);
}

const header = read('templates/header.tpl');
const footer = read('templates/footer.tpl');
const topbar = read('templates/partials/header/topbar.tpl');
const theme = read('theme.scss');
const stylesheet = read('scss/westgate/_topbar.scss');
const client = read('public/client.js');
const themeHooks = read('lib/theme.js');

assertIncludes(
	header,
	'<!-- IMPORT partials/header/topbar.tpl -->',
	'Header should mount the Westgate topbar partial'
);
assertExcludes(
	header,
	'<!-- IMPORT partials/sidebar-left.tpl -->',
	"Header should no longer render Harmony's left global sidebar"
);
assertExcludes(
	footer,
	'<!-- IMPORT partials/sidebar-right.tpl -->',
	"Footer should no longer render Harmony's right global sidebar"
);
assertIncludes(
	theme,
	'@import "./scss/westgate/topbar";',
	'theme.scss should import the focused topbar partial'
);
assertExcludes(
	theme,
	'@import "./scss/westgate/header";',
	'theme.scss should not import the removed brand banner stylesheet'
);
assertIncludes(
	stylesheet,
	'.wg-topbar',
	'Topbar styles should be scoped to .wg-topbar'
);
assertIncludes(
	stylesheet,
	'.wg-topbar__utility-list .visible-closed:not(.hidden)',
	'Topbar collapsed utility labels should not override hidden count badges'
);
assertIncludes(
	client,
	'initWestgateTopbar',
	'Client bundle should initialize Westgate topbar behavior'
);

[
	'component="sidebar/search"',
	'component="notifications"',
	'component="sidebar/drafts"',
].forEach((component) => {
	assertIncludes(topbar, component, `Topbar should preserve live NodeBB hook ${component}`);
});

[
	'<!-- IMPORT partials/sidebar/search.tpl -->',
	'<!-- IMPORT partials/sidebar/notifications.tpl -->',
	'<!-- IMPORT partials/sidebar/chats.tpl -->',
	'<!-- IMPORT partials/sidebar/drafts.tpl -->',
	'<!-- IMPORT partials/sidebar/user-menu.tpl -->',
].forEach((templateImport) => {
	assertIncludes(topbar, templateImport, `Topbar should reuse Harmony live partial ${templateImport}`);
});

[
	'Velessa Thorne',
	'Guildmaster Orin',
	'A letter left at the Undergate',
	'wg-topbar-demo',
	"localStorage.setItem('wg-topbar-presence'",
].forEach((fixture) => {
	assertExcludes(topbar, fixture, `Topbar should not ship preview fixture ${fixture}`);
});

assertIncludes(topbar, '{{{ if config.loggedIn }}}', 'Topbar should branch on the real logged-in state');
assertIncludes(topbar, '{{{ if canChat }}}', 'Chat controls should remain permission-gated');
assertIncludes(topbar, '{{{ if allowRegistration }}}', 'Registration should remain server-gated');
assertIncludes(topbar, '{{{ each navigation }}}', 'Topbar should render ACP Navigation items');
assertIncludes(topbar, '{./textClass}', 'Topbar should honor ACP Navigation text visibility classes');
assertExcludes(topbar, 'href="{relative_path}/admin"', 'Topbar should not hard-code the administrator link');
assertMatches(
	topbar,
	/<a\b(?=[^>]*class="[^"]*\bwg-topbar__brand\b[^"]*")(?=[^>]*aria-label="{config\.siteTitle}")/,
	'Topbar brand link should use the configured site title as its accessible name'
);
assertMatches(
	topbar,
	/<span\b(?=[^>]*class="[^"]*\bwg-topbar__brand-name\b[^"]*")[^>]*>{config\.siteTitle}<\/span>/,
	'Topbar brand text should render the configured site title'
);
assertExcludes(topbar, 'data-wg-menu', 'Topbar should rely on Bootstrap and NodeBB navigation instead of custom menu triggers');

assertMissing(
	'templates/partials/header/brand.tpl',
	'Theme should inherit Harmony brand markup instead of shipping the removed Westgate brand banner override'
);
assertMissing(
	'scss/westgate/_header.scss',
	'Removed brand banner styles should not remain in the theme'
);
assertMissing(
	'public/images/plum-header-bg.png',
	'Removed brand banner background should not remain in static assets'
);
assertExcludes(
	themeHooks,
	'brand-header',
	'Removed brand banner widget area should not remain registered'
);

const unreadDrawer = read('templates/partials/header/unread-drawer.tpl');
assertIncludes(
	topbar,
	'<!-- IMPORT partials/header/unread-drawer.tpl -->',
	'Topbar should mount the unread drawer before notifications'
);
assert(
	topbar.indexOf('partials/header/unread-drawer.tpl') < topbar.indexOf('partials/sidebar/notifications.tpl'),
	'Unread drawer should sit before the notifications item'
);
assertIncludes(
	unreadDrawer,
	'component="unread/count"',
	'Unread toggle should carry the live core count badge'
);
assertIncludes(
	unreadDrawer,
	'data-wg-unread-menu',
	'Unread dropdown menu should expose the JS mount hook'
);
assertMatches(
	topbar,
	/href="\{relative_path\}\/unread"[^>]*>[\s\S]*?component="unread\/count"/,
	'Mobile drawer actions should include an Unread link with count badge'
);
