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

import { IconAction, TextField, FloatingPanel, FieldsBehavior, PageFinder } from "@ax/components";
import { useModal } from "@ax/hooks";
import { isReqOk } from "@ax/helpers";
import type { IPage, IUrlField, Field, ISelectOption } from "@ax/types";
import { pages as pagesApi } from "@ax/api";
import { findAnchorsFromPage, findAnchorsFromTab, findTabsFromPage } from "./utils";

import * as S from "./style";

const UrlField = (props: IUrlFieldProps): JSX.Element => {
	const {
		value,
		onChange,
		showAdvanced,
		handlePanel,
		inFloatingPanel,
		disabled,
		handleValidation,
		validators,
		resetValidation,
	} = props;
	const { isOpen, toggleModal } = useModal();
	const [anchorOptions, setAnchorOptions] = useState<ISelectOption[]>([]);
	const [tabOptions, setTabOptions] = useState<ISelectOption[]>([]);
	const [isVisible, setIsVisible] = useState<boolean>(false);
	const [isTabsVisible, setTabsVisible] = useState<boolean>(false);
	const [internalPageName, setInternalPageName] = useState(null);
	const [pageData, setPageData] = useState<IPage | null>(null);

	const pageID = value?.linkTo ? value.linkTo : null;

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		const getPageInfo = async (id: number) => {
			const response = await pagesApi.getPageInfo(id);
			if (isReqOk(response.status)) {
				const { data } = response;
				setPageData(data);
				setInternalPageName(data.title);

				const tabs: ISelectOption[] = findTabsFromPage(data);
				setTabOptions(tabs);
				if (tabs.length > 0) setTabsVisible(true);

				const anchors: ISelectOption[] =
					tabs.length && value?.subSlug ? findAnchorsFromTab(data, value.subSlug) : findAnchorsFromPage(data);
				setAnchorOptions(anchors);
				if (anchors.length > 0 && (!tabs.length || (tabs.length && value?.subSlug))) setIsVisible(true);
			} else {
				setAnchorOptions([]);
			}
		};

		let isMounted = true;
		if (isMounted && pageID) {
			setTabsVisible(false);
			setIsVisible(false);
			getPageInfo(pageID);
		}

		return function cleanup() {
			isMounted = false;
		};
	}, [pageID]);

	const handleOnClick = () => {
		toggleModal();
		handlePanel?.(isOpen);
	};

	const handleReset = () => {
		onChange(null);
		setInternalPageName(null);
		resetValidation?.();
	};

	const handleSetPage = (page: IPage | IPage[]) => {
		toggleModal();
		const selectedPage = Array.isArray(page) ? page[0] : page;
		onChange({
			...value,
			href: null,
			linkTo: selectedPage.id,
			linkToURL: selectedPage.fullUrl,
			title: selectedPage.title,
			noFollow: !selectedPage.follow,
		});
		handleValidation?.(selectedPage.id.toString(), validators);
		handlePanel?.(isOpen);
	};

	const handleChange = (newValue: string) => onChange({ ...value, href: newValue });

	const handleTitleChange = (newValue: string) => onChange({ ...value, title: newValue });

	const handleNewTabChange = (newValue: boolean) => onChange({ ...value, newTab: newValue });

	const handleNoFollowChange = (newValue: boolean) => onChange({ ...value, noFollow: newValue });

	const handleAnchorChange = (newValue: string) => onChange({ ...value, anchor: newValue });

	const handleTabChange = (newValue: string) => {
		onChange({ ...value, subSlug: newValue });
		if (pageData && newValue) {
			const anchors: ISelectOption[] = findAnchorsFromTab(pageData, newValue);
			setAnchorOptions(anchors);
			if (anchors.length > 0) setIsVisible(true);
		} else {
			setIsVisible(false);
		}
	};

	const validator = { format: "fullURL" };
	const defensiveHref = value?.href ? value.href : "";

	let field = (
		<TextField
			{...props}
			value={defensiveHref}
			onChange={handleChange}
			placeholder="http://"
			icon="urlLink"
			onClickIcon={handleOnClick}
			validators={validator}
		/>
	);

	if (pageID) {
		field = (
			<S.PageSelectedWrapper>
				<S.PageField onClick={handleOnClick} data-testid="page-field">
					{internalPageName && `- ${internalPageName} -`}
				</S.PageField>
				<S.IconWrapper>
					<IconAction icon="unlink" onClick={handleReset} disabled={disabled} />
				</S.IconWrapper>
			</S.PageSelectedWrapper>
		);
	}

	const titleValue = value?.title ? value.title : internalPageName ? internalPageName : "";
	const noFollowValue =
		value && value.noFollow !== undefined
			? value.noFollow
			: pageData && pageData.follow !== undefined
				? !pageData.follow
				: false;

	const advancedFields = [
		{
			type: "TextField" as Field,
			name: "title",
			title: "Title",
			value: titleValue,
			onChange: handleTitleChange,
		},
		{
			type: "UniqueCheck" as Field,
			name: "newTab",
			options: [{ title: "Open in new tab" }],
			value: value?.newTab ? value.newTab : null,
			onChange: handleNewTabChange,
		},
		{
			type: "UniqueCheck" as Field,
			name: "noFollow",
			options: [{ title: "Add nofollow" }],
			value: noFollowValue,
			onChange: handleNoFollowChange,
		},
	];

	return (
		<S.UrlFieldWrapper data-testid="url-field-wrapper">
			{field}
			{value?.linkTo && isTabsVisible && (
				<S.AnchorWrapper>
					<FieldsBehavior
						title="Tab"
						options={tabOptions}
						name="tab"
						fieldType="Select"
						value={value.subSlug}
						onChange={handleTabChange}
						placeholder="Select Tab"
					/>
				</S.AnchorWrapper>
			)}
			{value?.linkTo && isVisible && (
				<S.AnchorWrapper>
					<FieldsBehavior
						title="Anchor"
						options={anchorOptions}
						name="anchor"
						fieldType="Select"
						value={value.anchor}
						onChange={handleAnchorChange}
						placeholder="Select Anchor"
					/>
				</S.AnchorWrapper>
			)}
			{showAdvanced && (
				<S.AdvancedWrapper>
					{advancedFields?.map((adField) => {
						return (
							<FieldsBehavior
								key={adField.name}
								options={adField.options}
								name={adField.name}
								title={adField.title}
								fieldType={adField.type}
								value={adField.value}
								onChange={adField.onChange}
							/>
						);
					})}
				</S.AdvancedWrapper>
			)}
			<FloatingPanel
				title="Select internal link"
				toggleModal={toggleModal}
				isOpen={isOpen}
				handlePanel={handlePanel}
				secondary={inFloatingPanel}
			>
				<S.Wrapper>
					<PageFinder onClick={handleSetPage} isOpen={isOpen} />
				</S.Wrapper>
			</FloatingPanel>
		</S.UrlFieldWrapper>
	);
};

export interface IUrlFieldProps {
	value?: IUrlField | null;
	title: string;
	onChange: (value: IUrlField | null) => void;
	showAdvanced: boolean;
	handlePanel?: (value: boolean) => void;
	inFloatingPanel?: boolean;
	disabled?: boolean;
	handleValidation?: (value: string, validators?: Record<string, unknown>) => void;
	resetValidation?: () => void;
	validators?: Record<string, unknown>;
}

export default memo(UrlField);
