import { useEffect, useRef, useState } from "react";
import DatePicker, { registerLocale } from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import en from "date-fns/locale/en-GB";

import {
	areEqualDates,
	stringToDate,
	getDateRange,
	getStringifyDateRange,
	dateToString,
	isValidDate,
	isValidDateRange,
} from "@ax/helpers";
import { useModal } from "@ax/hooks";

import DatePickerInput from "./DatePickerInput";
import * as S from "./style";

const DateField = (props: IDateFieldProps): JSX.Element => {
	const {
		value,
		onChange,
		error,
		mandatory,
		futureDate,
		pastDate,
		selectsRange = false,
		disabled,
		handleValidation,
		validators,
		editorID,
	} = props;

	const currentDate = new Date();
	const defaultValue = mandatory ? dateToString(currentDate, "yyyy/MM/dd") : null;
	const stringDate = value && typeof value === "number" ? dateToString(new Date(value * 1000)) : value;
	const dateValidators = { format: "date", ...validators };

	const dateValue = stringDate && (isValidDate(stringDate) || isValidDateRange(stringDate)) ? stringDate : defaultValue;
	const isRange = dateValue && dateValue.split(" - ").length > 1;
	const { isOpen, toggleModal } = useModal();

	const initialDate =
		dateValue && isRange
			? getDateRange(dateValue)
			: {
					start: dateValue ? stringToDate(dateValue) : null,
					end: dateValue ? stringToDate(dateValue) : null,
				};

	const dateFormat = "dd/MM/yyyy";

	const minDate = futureDate ? currentDate : null;
	const maxDate = pastDate ? currentDate : null;

	const [dates, setDates] = useState(initialDate);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		setDates(initialDate);
	}, [editorID]);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		if ((!value || value.length === 0) && mandatory) {
			const { start, end } = initialDate;
			handleOnChange([start, end]);
		}
	}, []);

	registerLocale("en", en);

	const handleOnChange = (dates: any) => {
		const start = dates.length ? dates[0] : dates;
		const end = dates.length ? dates[1] : null;

		const equalRangeDates = areEqualDates(start, end);

		const rangeDates = {
			start,
			end: equalRangeDates ? start : end,
		};

		const selectedDate = getStringifyDateRange(start, end, "yyyy/MM/dd");

		setDates(rangeDates);
		onChange(selectedDate);

		handleValidation?.(selectedDate, dateValidators);
	};

	const { start, end } = dates;

	const ref = useRef(null);
	const CustomInput = (
		<DatePickerInput
			dates={dates}
			handleChange={handleOnChange}
			ref={ref}
			isOpen={isOpen}
			error={error}
			disabled={disabled}
			handleValidation={handleValidation}
			validators={dateValidators}
		/>
	);

	return (
		<S.DatePickerWrapper data-testid="dateWrapper">
			<DatePicker
				locale={"en"}
				selected={start}
				onChange={handleOnChange}
				startDate={start}
				endDate={end}
				dateFormat={dateFormat}
				selectsRange={selectsRange}
				disabledKeyboardNavigation
				shouldCloseOnSelect={false}
				customInput={CustomInput}
				onCalendarClose={toggleModal}
				onCalendarOpen={toggleModal}
				minDate={minDate}
				maxDate={maxDate}
				disabled={disabled}
			/>
		</S.DatePickerWrapper>
	);
};

export interface IDateFieldProps {
	value: string | any;
	selectsRange: boolean;
	onChange: (value: any) => void;
	error?: boolean;
	mandatory?: boolean;
	futureDate?: boolean;
	pastDate?: boolean;
	disabled?: boolean;
	handleValidation?: (value: string, validators?: Record<string, unknown>) => void;
	validators?: Record<string, unknown>;
	editorID: number;
}

export default DateField;
