import { getSchema } from "@ax/helpers";
import type { IDataPack, IGriddoTheme, ITemplateOption, IThemeElements } from "@ax/types";

import { config } from "components";

const themes = config.schemas.config.themes;

const getDefaultTheme = (): string => {
	const defaultTheme = (themes as IGriddoTheme[]).find((theme) => theme.default);
	const theme = defaultTheme ? defaultTheme.value : themes[0].value;
	return theme;
};

const getThemeElements = (theme: string): IThemeElements | undefined => {
	return (themes as IGriddoTheme[]).find((griddoTheme) => griddoTheme.value === theme)?.elements;
};

const filterThemeModules = (themeElements: IThemeElements | null, elements: string[]): string[] => {
	if (themeElements === null) return elements;

	const { exclude, include } = themeElements;

	let filteredElements: string[] = elements;
	if (exclude && Array.isArray(exclude.modules)) {
		filteredElements = elements.filter((element: string) => !exclude.modules?.includes(element));
	} else if (include && Array.isArray(include.modules)) {
		filteredElements = elements.filter((element: string) => {
			const schema = getSchema(element);
			return schema?.schemaType === "component" ? true : include.modules?.includes(element);
		});
	}

	return filteredElements;
};

const filterThemeTemplates = (
	themeElements: IThemeElements | null,
	templates: ITemplateOption[],
): ITemplateOption[] => {
	if (themeElements === null) return templates;

	const { exclude, include } = themeElements;

	let filteredElements: ITemplateOption[] = templates;
	if (exclude && Array.isArray(exclude.templates)) {
		filteredElements = templates.filter((template) => !exclude.templates?.includes(template.value));
	} else if (include && Array.isArray(include.templates)) {
		filteredElements = templates.filter(
			(template) => include.templates?.includes(template.value) || template.value === "BasicTemplate",
		);
	}

	return filteredElements;
};

const filterThemeDatapacks = (themeElements: IThemeElements | null, datapacks: IDataPack[]): IDataPack[] => {
	if (themeElements === null) return datapacks;

	const { exclude, include } = themeElements;

	let filteredElements: IDataPack[] = datapacks;
	if (exclude && Array.isArray(exclude.datapacks)) {
		filteredElements = datapacks.filter((datapack) => !exclude.datapacks?.includes(datapack.id));
	} else if (include && Array.isArray(include.datapacks)) {
		filteredElements = datapacks.filter((datapack) => include.datapacks?.includes(datapack.id));
	}

	return filteredElements;
};

const isTemplateExcludedFromTheme = (themeElements: IThemeElements | null, template: string): boolean => {
	if (themeElements === null) return false;

	const { exclude, include } = themeElements;

	if (
		(exclude && Array.isArray(exclude.templates) && exclude.templates.includes(template)) ||
		(include &&
			Array.isArray(include.templates) &&
			!include.templates.includes(template) &&
			template !== "BasicTemplate")
	) {
		return true;
	}

	return false;
};

export {
	filterThemeDatapacks,
	filterThemeModules,
	filterThemeTemplates,
	getDefaultTheme,
	getThemeElements,
	isTemplateExcludedFromTheme,
};
