import { useEffect, useRef, useState } from "react";
import { connect } from "react-redux";

import { Button, EmptyState, MenuItem, Modal, Tooltip } from "@ax/components";
import { filterThemeTemplates, isGlobalStructuredData, isStructuredDataFromPage } from "@ax/helpers";
import type { IModal, IRootState, IStructuredData, ITemplateOption, IThemeElements } from "@ax/types";

import ContentItem from "./ContentItem";
import { getOptionsByDataPacks } from "./utils";
import PageImporter from "./PageImporter";

import * as S from "./style";

const NewContentModal = (props: INewContentModalProps) => {
	const {
		isOpen,
		selectedValue,
		filters,
		structuredData,
		themeElements,
		values,
		theme,
		toggleModal,
		createContent,
		setPagesToImport,
		importPage,
	} = props;

	const allFilters = [{ label: "All content", value: "all" }, ...filters];

	const valueObj = values.find((value) => value.name === selectedValue);
	const currentDataPack = valueObj?.dataPacks?.length ? valueObj.dataPacks[0] : valueObj?.type || "";
	const currentType = valueObj ? currentDataPack : "all";

	const initialState: IState = {
		items: {},
		selectedOption: valueObj ? { ...valueObj, currentDataPack } : null,
		selectedType: currentType,
		isImporterOpen: false,
		searchQuery: "",
	};

	const [state, setState] = useState(initialState);
	const listRef = useRef<HTMLDivElement>(null);

	const filteredValues = filterThemeTemplates(themeElements, values);
	const itemsByDataPack = getOptionsByDataPacks(filters, filteredValues, structuredData.site);

	const structuredDataItem = structuredData.site.find(
		(data) => data.id.toLowerCase() === state.selectedOption?.type.toLowerCase(),
	);

	const isOptionGlobal = structuredDataItem ? isGlobalStructuredData(structuredDataItem.id) : false;
	const isDataFromPage = structuredDataItem ? isStructuredDataFromPage(structuredDataItem.id) : false;
	const isOptionImportable = isOptionGlobal && isDataFromPage && state.selectedOption?.mode === "detail";

	// biome-ignore lint/correctness/useExhaustiveDependencies: to avoid infinite loop
	useEffect(() => {
		let filteredItems: Record<string, ITemplateOption[]> = {};

		if (state.searchQuery.trim().length) {
			filteredItems.result = filteredValues.filter((value) =>
				value.title.toLowerCase().includes(state.searchQuery.toLowerCase()),
			);
		} else {
			filteredItems =
				state.selectedType === "all"
					? itemsByDataPack
					: state.selectedType && itemsByDataPack[state.selectedType]
						? { [state.selectedType]: itemsByDataPack[state.selectedType] }
						: {};
		}

		setState((state) => ({ ...state, items: filteredItems }));
		state.isImporterOpen && toggleImporter();

		if (listRef.current) {
			listRef.current.scrollTo(0, 0);
		}
	}, [state.selectedType, state.searchQuery]);

	// biome-ignore lint/correctness/useExhaustiveDependencies: avoid infinite loop
	useEffect(() => {
		const handleKeyPress = (event: KeyboardEvent) => {
			if (event.key === "Enter" && !state.isImporterOpen) {
				handleCreateContent();
			}
		};

		document.addEventListener("keydown", handleKeyPress);

		return () => {
			document.removeEventListener("keydown", handleKeyPress);
		};
	}, [state.selectedOption, state.isImporterOpen]);

	const setType = (type: string) =>
		setState((state) => ({ ...state, selectedType: type, selectedOption: null, searchQuery: "" }));

	const toggleImporter = () => setState((state) => ({ ...state, isImporterOpen: !state.isImporterOpen }));

	const setSearchQuery = (searchQuery: string) => setState((state) => ({ ...state, searchQuery, selectedType: "all" }));

	const handleCreateContent = () => {
		if (!state.selectedType || !state.selectedOption) return;

		if (isOptionImportable) {
			toggleImporter();
		} else {
			const structuredDataItem = structuredData.site.find(
				(data) => state.selectedOption && data.id.toLowerCase() === state.selectedOption.type.toLowerCase(),
			);
			const isStructuredData = !!structuredDataItem && !structuredDataItem.fromPage;
			createContent(isStructuredData, state.selectedOption.name);
		}
	};

	return (
		<Modal
			isOpen={isOpen}
			hide={toggleModal}
			searchAction={setSearchQuery}
			searchValue={state.searchQuery}
			size="XL"
			title="New content"
		>
			{
				<S.Wrapper>
					<S.LeftColumn>
						<S.MenuWrapper>
							{allFilters.map((item, i: number) => {
								const handleClick = () => item.value !== state.selectedType && setType(item.value);
								const isSelected = item.value === state.selectedType;
								const selectedClass = isSelected ? "selected" : "";
								return (
									<MenuItem key={`${item.value}${i}`} className={selectedClass} onClick={handleClick}>
										<S.NavLink>
											<S.Link active={isSelected}>{item.label}</S.Link>
										</S.NavLink>
									</MenuItem>
								);
							})}
						</S.MenuWrapper>
					</S.LeftColumn>
					<S.RightColumn>
						{state.isImporterOpen ? (
							<PageImporter
								structuredDataID={state.selectedOption?.type || ""}
								setPagesToImport={setPagesToImport}
								title={state.selectedOption?.title || ""}
								toggleImporter={toggleImporter}
								importPage={importPage}
							/>
						) : (
							<>
								<S.Content ref={listRef}>
									{Object.keys(state.items).map((key: string) => {
										const pack = filters.find((filter) => filter.value === key);
										return (
											<S.DataWrapper key={key}>
												<S.DataTitle hasBold={state.selectedType !== "all"}>{pack?.label}</S.DataTitle>
												{!state.items[key].length && !!state.searchQuery.trim().length ? (
													<S.EmptyStateWrapper>
														<EmptyState
															icon="search"
															title="Oh! No Results Found"
															message="We couldn’t find what you are looking for. Please, try another search."
														/>
													</S.EmptyStateWrapper>
												) : (
													<S.DataContent>
														{state.items[key].map((item) => {
															const structuredDataItem = structuredData.site.find(
																(data) => data.id.toLowerCase() === item.type.toLowerCase(),
															);

															const handleClick = () =>
																setState((state) => ({ ...state, selectedOption: { ...item, currentDataPack: key } }));

															const isSelected =
																item.name === state.selectedOption?.name &&
																key === state.selectedOption.currentDataPack;

															return (
																<ContentItem
																	key={item.name}
																	item={item}
																	theme={theme}
																	isSelected={isSelected}
																	onClick={handleClick}
																	structuredData={structuredDataItem}
																	pack={pack?.label}
																	listRef={listRef}
																/>
															);
														})}
													</S.DataContent>
												)}
											</S.DataWrapper>
										);
									})}
								</S.Content>
								<S.ModalFooter>
									<Button type="button" buttonStyle="minimal" onClick={toggleModal}>
										Close
									</Button>
									<Tooltip content={!state.selectedOption ? "Select one item first" : undefined}>
										<Button type="button" disabled={!state.selectedOption} onClick={handleCreateContent}>
											{isOptionImportable ? "Next" : "Create New"}
										</Button>
									</Tooltip>
								</S.ModalFooter>
							</>
						)}
					</S.RightColumn>
				</S.Wrapper>
			}
		</Modal>
	);
};

export interface IOptionFilter {
	label: string;
	value: string;
	isData?: boolean;
	special?: string;
	mode?: string;
}

interface IState {
	items: Record<string, ITemplateOption[]>;
	selectedOption: ISelectedOption | null;
	selectedType: string | null;
	isImporterOpen: boolean;
	searchQuery: string;
}

interface ISelectedOption extends ITemplateOption {
	currentDataPack: string;
}

interface INewContentModalProps extends IModal {
	setPagesToImport: (pages: number[]) => void;
	createContent: (isStructuredData: boolean, value: string) => void;
	importPage: () => void;
	filters: IOptionFilter[];
	values: ITemplateOption[];
	selectedValue: string | null;
	theme: string;
	structuredData: { global: IStructuredData[]; site: IStructuredData[] };
	themeElements: IThemeElements | null;
}

const mapStateToProps = (state: IRootState) => ({
	structuredData: state.structuredData.structuredData,
	themeElements: state.sites.themeElements,
});

export default connect(mapStateToProps)(NewContentModal);
