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

import { Button, CheckField, EmptyState, Icon, Loader, NoteField, SearchField } from "@ax/components";
import type { IGetGlobalPagesParams, IPage, IRootState } from "@ax/types";
import { useBulkSelection } from "@ax/hooks";
import { isReqOk } from "@ax/helpers";
import { sites } from "@ax/api";

import PageItem from "./PageItem";

import * as S from "./style";

const PageImporter = (props: IPageImporterProps) => {
	const { lang, structuredDataID, setPagesToImport, siteID, title, toggleImporter, importPage } = props;

	const [pages, setPages] = useState<IPage[]>([]);
	const [allPages, setAllPages] = useState<IPage[] | null>(null);
	const [searchQuery, setSearchQuery] = useState<string>("");
	const [isLoading, setIsLoading] = useState(true);

	const pageIds = pages.map((page) => page.id);
	const { resetBulkSelection, selectedItems, isSelected, checkState, addToBulkSelection, selectAllItems } =
		useBulkSelection(pageIds);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	const getParams = useCallback(() => {
		const params: IGetGlobalPagesParams = {
			page: 1,
			itemsPerPage: 100,
			deleted: false,
			filterStructuredData: structuredDataID.toUpperCase(),
			query: searchQuery,
			excludeSite: siteID,
			liveStatus: "active,upload-pending",
		};

		return params;
	}, [lang.locale, searchQuery]);

	const handleGetGlobalPages = async () => {
		try {
			setIsLoading(true);
			const params = getParams();
			const response = await sites.getGlobalPagesLight(params);
			if (isReqOk(response.status)) {
				const {
					data: { items },
				} = response;
				setPages(items);
				if (!allPages) setAllPages(items);
			}
			setIsLoading(false);
		} catch (error) {
			console.log(error);
		}
	};

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

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		setPagesToImport(selectedItems.all);
	}, [selectedItems]);

	const handleSelectAll = () => {
		checkState.isAllSelected ? resetBulkSelection() : selectAllItems();
	};

	const SelectedItem = (props: IPage): JSX.Element => {
		const { id, title } = props;
		const removeItem = () => addToBulkSelection({ value: id, isChecked: false });

		return (
			<S.SelectedItem>
				<S.IconWrapper onClick={removeItem}>
					<Icon name="close" size="16" />
				</S.IconWrapper>
				<S.SelectedName>{title}</S.SelectedName>
			</S.SelectedItem>
		);
	};

	const selectedPages = allPages?.filter((page: IPage) => selectedItems.all.includes(page.id));

	if (isLoading) {
		return (
			<S.LoadingWrapper>
				<Loader name="circle" />
			</S.LoadingWrapper>
		);
	}

	return (
		<>
			<S.Content>
				<S.DataWrapper>
					<S.DataTitle hasBold={true}>{title}</S.DataTitle>
					{pages.length ? (
						<S.ImporterContent>
							<S.ColumnWrapper>
								<NoteField
									value={{
										text: (
											<>
												Please note that only pages that <strong>you do not currently have on the site</strong> are
												displayed.
											</>
										),
									}}
								/>
								<S.SearchWrapper>
									<S.CheckAll>
										<CheckField
											key="selectAll"
											name="selectAll"
											value="selectAll"
											onChange={handleSelectAll}
											checked={checkState.isAllSelected}
											indeterminate={checkState.indeterminate}
											disabled={false}
											error={false}
										/>
									</S.CheckAll>
									<SearchField onChange={setSearchQuery} value={searchQuery} focus={false} placeholder="Search" />
								</S.SearchWrapper>
								<S.PageList>
									{!!pages.length &&
										pages.map((page: IPage) => {
											const isSelect = isSelected(page.id);
											return (
												<PageItem
													key={page.id}
													page={page}
													structuredDataID={structuredDataID}
													isSelected={isSelect}
													addToBulk={addToBulkSelection}
												/>
											);
										})}
								</S.PageList>
							</S.ColumnWrapper>
							<S.ColumnWrapper>
								<S.SelectedWrapper>
									<S.SelectedTitle>Pages Selected</S.SelectedTitle>
									{selectedPages?.length ? (
										<S.SelectedList>
											{selectedPages?.map((page: IPage) => (
												<SelectedItem key={page.id} {...page} />
											))}
										</S.SelectedList>
									) : (
										<S.SelectedInfo>
											You have to select at least one page, and you can select as many pages as you like.
										</S.SelectedInfo>
									)}
								</S.SelectedWrapper>
							</S.ColumnWrapper>
						</S.ImporterContent>
					) : (
						<S.EmptyStateWrapper>
							<EmptyState
								title="All Set!"
								message={
									<>
										You've already added all the available pages of this
										<br />
										content type to your site.
									</>
								}
							/>
						</S.EmptyStateWrapper>
					)}
				</S.DataWrapper>
			</S.Content>
			<S.ModalFooter>
				<Button type="button" buttonStyle="text" onClick={toggleImporter}>
					Go Back
				</Button>
				<Button type="button" onClick={importPage} disabled={!selectedPages?.length}>
					Add pages
				</Button>
			</S.ModalFooter>
		</>
	);
};

interface IPageImporterProps {
	siteID: number | undefined;
	lang: { locale: string; id: number };
	structuredDataID: string;
	title: string;
	setPagesToImport: (pages: number[]) => void;
	toggleImporter: () => void;
	importPage: () => void;
}

const mapStateToProps = (state: IRootState) => ({
	siteID: state.sites.currentSiteInfo?.id,
	lang: state.app.lang,
});

export default connect(mapStateToProps)(PageImporter);
