import { useEffect, useRef, useState } from "react";

import { Button, Icon } from "@ax/components";
import { LOCALE } from "@ax/locales";

import { Select } from "../Fields";

import * as S from "./style";

const SearchField = (props: ISearchFieldProps): JSX.Element => {
	const {
		onChange,
		placeholder,
		closeOnInactive = false,
		searchOnEnter = true,
		disabled = false,
		searchFilters,
		onFilterChange,
		small,
		focus = true,
		size = "M",
		value,
	} = props;

	const [isOpen, setIsOpen] = useState(!!(value && value.trim() !== ""));
	const [inputValue, setInputValue] = useState(value || "");
	const [selectValue, setSelectValue] = useState<string>("");
	const inputRef = useRef<HTMLInputElement | null>(null);
	const showField = isOpen || !closeOnInactive;

	useEffect(() => {
		if (focus && showField && inputRef.current) {
			inputRef.current.focus();
		}
	}, [focus, showField]);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		if (value !== inputValue) {
			setInputValue(value || "");
		}
	}, [value]);

	const toggleField = () => setIsOpen(!isOpen);

	const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
		const newValue = e.target.value;
		setInputValue(newValue);
		if (!searchOnEnter) {
			onChange(newValue);
		}
	};

	const handleClear = () => {
		setInputValue("");
		onChange("");
		setSelectValue("");
	};

	const handleClose = () => {
		toggleField();
		handleClear();
	};

	const handleClick = () => {
		closeOnInactive ? handleClose() : handleClear();
	};

	const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
		if (searchOnEnter && e.key === "Enter") {
			onChange(inputValue);
		}
	};

	const handleSelectChange = (value: string) => {
		setSelectValue(value);
		onFilterChange?.(value);
	};

	return (
		<S.Wrapper data-testid="search-field-wrapper">
			{showField ? (
				<S.FieldWrapper closeOnInactive={closeOnInactive} disabled={disabled} data-testid="field-wrapper">
					{searchFilters?.length && (
						<>
							<S.FilterWrapper data-testid="filter-wrapper">
								<Select
									name="filterSelect"
									value={selectValue}
									options={searchFilters}
									onChange={handleSelectChange}
									type="inline"
									placeholder="Filter by"
								/>
							</S.FilterWrapper>
							<S.Separator />
						</>
					)}
					<S.Input
						type="text"
						value={inputValue}
						onChange={handleChange}
						onKeyDown={handleKeyDown}
						placeholder={placeholder || LOCALE.common.typeSomething}
						closeOnInactive={closeOnInactive}
						disabled={disabled}
						data-testid="search-input"
						small={small}
						ref={inputRef}
						inputSize={size}
						name="searchInput"
					/>

					{searchOnEnter && <S.HelpText hide={!inputValue.trim()}>Press ENTER</S.HelpText>}
					{closeOnInactive || inputValue.length > 0 ? (
						<S.CloseWrapper data-testid="icon-close-wrapper">
							<S.CloseButton type="button" onClick={handleClick} buttonStyle="minimal">
								{LOCALE.common.close}
							</S.CloseButton>
						</S.CloseWrapper>
					) : (
						<S.IconSearchWrapper disabled={disabled} data-testid="icon-search-wrapper-2">
							<Icon name="search" size="24" />
						</S.IconSearchWrapper>
					)}
				</S.FieldWrapper>
			) : (
				<S.IconSearchWrapper disabled={disabled} onClick={toggleField} data-testid="icon-search-wrapper">
					<Icon name="search" size="24" />
				</S.IconSearchWrapper>
			)}
		</S.Wrapper>
	);
};

export interface ISearchFieldProps {
	onChange(query: string): void;
	placeholder?: string;
	closeOnInactive?: boolean;
	searchOnEnter?: boolean;
	disabled?: boolean;
	searchFilters?: any;
	onFilterChange?(filter: string): void;
	small?: boolean;
	focus?: boolean;
	size?: "L" | "M" | "S" | "XS" | "XXS";
	value?: string;
}

export default SearchField;
