import { useEffect, useState } from "react";

import { CheckGroup, FloatingMenu, Icon, ListTitle, SearchField } from "@ax/components";
import { areEquals } from "@ax/helpers";
import type { IFilterValue, IQueryValue } from "@ax/types";

import * as S from "./style";

const CheckGroupFilter = (props: ITypeFilterProps): JSX.Element => {
	const {
		label,
		description,
		filterItems,
		filters,
		pointer,
		value,
		selectAllOption,
		initialState,
		multipleSelection = true,
		menuPosition = "center",
		search = false,
	} = props;

	const arrayValues = Array.isArray(value) && value.length ? value.map((val) => val.value) : initialState;
	const [selectedValue, setSelectedValue] = useState(arrayValues);
	const [filteredOptions, setFilteredOptions] = useState(filters);
	const [hasSearch, setHasSearch] = useState(search && !!filters.length);

	useEffect(() => {
		const arrayValues = Array.isArray(value) && value.length ? value.map((val) => val.value) : initialState;
		setSelectedValue(arrayValues);
	}, [value, initialState]);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		setHasSearch(search && !!filters.length);
		setFilteredOptions(filters);
	}, [filters]);

	const setFilterQuery = (selection: any) => {
		if (!selection.length) {
			selection = initialState;
		}
		setSelectedValue(selection);
		const queryFilters: IQueryValue[] = selection.map((value: string | number) => {
			const label = filters.find((opt) => opt.value === value);
			return { value, label: label?.title || "" };
		});
		filterItems(pointer, queryFilters);
	};

	const filterOptions = (query: string) => {
		const filteredSites =
			query.trim().length > 0
				? filters.filter((value) =>
						value.title.toLowerCase().replace(" ", "").includes(query.toLowerCase().replace(" ", "")),
					)
				: filters;
		setFilteredOptions(filteredSites);
	};

	const cleanSearchOnClose = () => filterOptions("");

	const isActive = !areEquals(selectedValue, initialState);

	const Header = () => (
		<S.StyledHeader isActive={isActive}>
			{label}
			<S.IconsWrapper>
				{isActive ? <Icon name="Filter" size="16" /> : <Icon name="DownArrow" size="16" />}
			</S.IconsWrapper>
		</S.StyledHeader>
	);

	const hasAllOption = filteredOptions.find((opt) => opt.value === "all");

	return (
		<FloatingMenu
			Button={Header}
			closeOnSelect={!multipleSelection}
			isCheckGroup={true}
			position={menuPosition}
			hasMargin={false}
			fixedWidth={search ? 263 : undefined}
			actionOnClose={cleanSearchOnClose}
		>
			<ListTitle>{description}</ListTitle>
			{hasSearch && (
				<S.SearchWrapper>
					<SearchField onChange={filterOptions} size="XXS" searchOnEnter={false} placeholder="Search" />
				</S.SearchWrapper>
			)}
			<S.ChecksWrapper>
				<CheckGroup
					options={filteredOptions}
					value={selectedValue}
					onChange={setFilterQuery}
					selectAllOption={hasAllOption ? selectAllOption : undefined}
					multipleSelection={multipleSelection}
				/>
			</S.ChecksWrapper>
		</FloatingMenu>
	);
};

interface ITypeFilterProps {
	label: string;
	description: string;
	filterItems(pointer: string, filter: IQueryValue[]): void;
	filters: IFilterValue[];
	pointer: string;
	value: IQueryValue[];
	selectAllOption: string;
	initialState: string[];
	multipleSelection?: boolean;
	menuPosition?: string;
	search?: boolean;
}

export default CheckGroupFilter;
