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

import { IDataPack, IDataPackCategory, IRootState, ISite } from "@ax/types";
import { getDataPackSchema, sortBy } from "@ax/helpers";
import { Icon, Loader } from "@ax/components";

import { dataPacksActions } from "@ax/containers/Settings/DataPacks";
import SidePanel from "./SidePanel";
import Filter from "./Filter";
import SortFilter from "./SortFilter";

import * as S from "./style";

const AddModal = (props: IProps) => {
	const { toggleModal, getAvailableDataPacks, isLoading, available, addDataPacks, categories, currentSiteInfo } = props;

	if (!currentSiteInfo) {
		throw new Error(`ERROR: User reached DataPacks with null site info`);
	}

	const initialState: IState = {
		packsSelected: [],
		currentFilter: null,
		currentOrder: null,
	};

	const [state, setState] = useState(initialState);

	useEffect(() => {
		getAvailableDataPacks(state.currentFilter);
	}, [getAvailableDataPacks, state.currentFilter]);

	let items = [...available];
	if (state.currentOrder) {
		const { field, desc } = state.currentOrder;

		items = items && items.sort(sortBy(field, desc));
	}

	const _handleClick = (item: IDataPack) => () => {
		if (state.packsSelected.find((i: IDataPack) => i.id === item.id)) {
			const newItems = state.packsSelected.filter((i: IDataPack) => i.id !== item.id);
			setState({ ...state, packsSelected: newItems });
		} else {
			setState({ ...state, packsSelected: [...state.packsSelected, item] });
		}
	};

	const activateDataPack = () => {
		const packIDs = state.packsSelected.map((pack: IDataPack) => pack.id).join();
		addDataPacks(packIDs);
		toggleModal();
	};

	const uncheckAll = () => {
		setState({ ...state, packsSelected: [] });
	};

	const setFilter = (categoryID: string | null) => {
		const filter = categoryID ? `&category=${categoryID}` : null;
		setState({ ...state, currentFilter: filter });
	};

	const setOrder = (order: any) => {
		setState({ ...state, currentOrder: order });
	};

	return (
		<S.Wrapper>
			<S.GridWrapper>
				<S.FiltersWrapper>
					<Filter items={categories} setFilter={setFilter} />
					<SortFilter setOrder={setOrder} />
				</S.FiltersWrapper>
				{isLoading ? (
					<S.LoadingWrapper>
						<Loader name="circle" />
					</S.LoadingWrapper>
				) : (
					<S.Grid>
						{items &&
							items.map((item: IDataPack, index: number) => {
								const isSelected = state.packsSelected.find((i: IDataPack) => i.id === item.id);
								const schema = getDataPackSchema(item.id);
								if (!schema) return <></>;
								const { image } = schema;
								const imageUrl = typeof image === "string" ? image : image[currentSiteInfo.theme];

								return (
									<S.GridItem key={item.title + index}>
										<S.PackWrapper onClick={_handleClick(item)} selected={!!isSelected}>
											<S.ImageWrapper>
												<img src={imageUrl} alt={item.title} />
											</S.ImageWrapper>
											<S.Title>{item.title}</S.Title>
											<S.IconUnchecked>
												<Icon name="emptyCheck" size="24" />
											</S.IconUnchecked>
											<S.IconChecked>
												<Icon name="successSolid" size="24" />
											</S.IconChecked>
										</S.PackWrapper>
									</S.GridItem>
								);
							})}
					</S.Grid>
				)}
			</S.GridWrapper>
			<SidePanel selected={state.packsSelected} activatePacks={activateDataPack} uncheckAll={uncheckAll} />
		</S.Wrapper>
	);
};

interface IState {
	packsSelected: IDataPack[];
	currentFilter: string | null;
	currentOrder: { field: string; desc: boolean } | null;
}

interface IProps {
	isLoading: boolean;
	available: IDataPack[];
	categories: IDataPackCategory[];
	currentSiteInfo: ISite | null;
	toggleModal: () => void;
	getAvailableDataPacks: (queryParams: string | null) => void;
	addDataPacks: (dataPackID: string, fromConfig?: boolean) => void;
}

const mapStateToProps = (state: IRootState) => ({
	available: state.dataPacks.available,
	categories: state.dataPacks.categories,
	isLoading: state.app.isLoading,
	currentSiteInfo: state.sites.currentSiteInfo,
});

const mapDispatchToProps = {
	getAvailableDataPacks: dataPacksActions.getAvailableSiteDataPacks,
	addDataPacks: dataPacksActions.addSiteDataPack,
};

export default connect(mapStateToProps, mapDispatchToProps)(AddModal);
