import { InputBase, IconButton } from "@mui/material";
import SearchIcon from "@mui/icons-material/Search";
import styles from "./index.module.css";
import cloneDeep from "lodash/cloneDeep";
import { getScrollLoader } from "@/utils/util";
import { useState, useCallback, useEffect, useMemo } from "react";
import { getOperatorList } from "@/api/project_api";
import CircularProgress from "@mui/material/CircularProgress";
import useMyRequest from "@/hooks/useMyRequest";
import { useStores } from "@/store";
import { toJS } from "mobx";
import { ITask } from "@/views/Project/ProjectSubmitWork/interface";

type IProps = {
	operatorList: ITask[];
	setOperatorList: any;
};

const OperatorList = (props: IProps) => {
	const { operatorList, setOperatorList } = props; // 流程图中流算子列表
	const { currentProjectStore } = useStores();
	const [list, setList] = useState<ITask[]>([]); // 算子列表
	const productId = toJS(currentProjectStore.currentProductInfo.id); // 产品ID
	const [keyword, setKeyword] = useState(""); // 搜索算子列表时的关键词
	const [dragItem, setDragItem] = useState<any>({}); // 拖拽的算子
	const [page, setPage] = useState(0); // 算子列表页码
	const [isLastPage, setIsLastPage] = useState(false); // 是否是最后一页

	// 应该一个批算子里可以有多个流算子   流算子也可以重复   所以需要在流算子后加一个_${count}  加上operatorList可能有缓存数据， 所以不一定是1开头
	const count = useMemo(() => {
		if (operatorList.length === 0) {
			return 1;
		} else {
			const countArr = operatorList.map((operatorLi) => {
				const _index = operatorLi.id.indexOf("_");
				if (_index === -1) {
					return 1;
				} else {
					return Number(operatorLi.id.slice(_index + 1));
				}
			});
			const maxCount = Math.max(...countArr);
			return maxCount + 1;
		}
	}, [operatorList]);

	// 获取算子列表
	const { run: getOperatorListRun, loading } = useMyRequest(getOperatorList, {
		onSuccess: (res) => {
			let arr = res?.data?.content.map((item: any) => {
				return {
					...item,
					edges: [],
				};
			});
			setIsLastPage(res?.data?.last);
			setList([...list, ...arr]);
		},
	});

	// 获取算子列表方法
	const getOperatorListFun = useCallback(
		(keyword: string = "", page = 0) => {
			getOperatorListRun({
				productId: productId as string,
				keyword,
				page,
				size: 20,
			});
		},
		[productId, getOperatorListRun]
	);

	// 打开弹窗时获取算子列表
	useEffect(() => {
		getOperatorListFun();
	}, [getOperatorListFun]);

	// 算子列表搜索关键词变化
	const keywordChange = (e: any) => {
		if (e.target.value.length <= 30) {
			setKeyword(e.target.value);
		}
	};

	// 回车搜索
	const handleKeywordKeyUp = (e: any) => {
		if (e.keyCode === 13) {
			setList([]);
			setKeyword(e.target.value);
			setPage(0);
			getOperatorListFun(e.target.value, 0);
		}
	};

	// 滚动触发
	const handleScroll = (e: any) => {
		// 满足快滚动到底部时开始加载
		if (getScrollLoader(e)) {
			if (loading || isLastPage) {
				return;
			} else {
				getOperatorListFun(keyword, page + 1);
				setPage(page + 1);
			}
		}
	};

	// 渲染六个小点样式
	const randerIcon = () => {
		return (
			<div className={styles.icon}>
				<div className={styles.iconLi}>
					<div className={styles.iconItem}></div>
					<div className={styles.iconItem}></div>
				</div>
				<div className={styles.iconLi}>
					<div className={styles.iconItem}></div>
					<div className={styles.iconItem}></div>
				</div>
				<div className={styles.iconLi}>
					<div className={styles.iconItem}></div>
					<div className={styles.iconItem}></div>
				</div>
			</div>
		);
	};

	/** 拖拽开始 */
	const onDragStart = (item: any) => {
		setDragItem(item);
	};

	/** 生成批流副本 */
	const getNewOperatorItem = useCallback(
		(task: ITask, x: number, y: number) => {
			const newEdges =
				task?.edges &&
				task?.edges.map((every) => {
					return {
						...every,
						source: `${every.source}_${count}`,
						target: `${every.target}_${count}`,
					};
				});
			return {
				...task,
				id: `${task.id}_${count}`,
				position: {
					x: x,
					y: y,
				},
				edges: newEdges.length ? newEdges : task?.edges,
			};
		},
		[count]
	);

	/** 拖拽结束 */
	const onDragEnd = useCallback(
		(e: React.DragEvent<HTMLDivElement>) => {
			const dom = document.getElementById("customOperatorFlow");
			const clientX = e.clientX;
			const clientY = e.clientY;
			const upperLeftPointX = Number(dom?.offsetLeft);
			const upperLeftPointY = Number(dom?.offsetTop);
			const lowerRightX = Number(upperLeftPointX) + Number(dom?.offsetWidth);
			const lowerRightY = Number(upperLeftPointY) + Number(dom?.offsetHeight);
			if (
				clientX > upperLeftPointX &&
				clientY > upperLeftPointY &&
				clientX < lowerRightX &&
				clientY < lowerRightY
			) {
				const newDragItem = cloneDeep(dragItem);
				const newOperatorItem = getNewOperatorItem(
					newDragItem,
					clientX - upperLeftPointX,
					clientY - upperLeftPointY - 42
				);
				const newVal = cloneDeep(operatorList);
				newVal.push(newOperatorItem);
				setOperatorList(newVal);
			}
		},
		[dragItem, operatorList, setOperatorList, getNewOperatorItem]
	);

	return (
		<div className={styles.operatorList}>
			<div className={styles.searchBox}>
				<IconButton
					type="submit"
					className={styles.searchButton}
					aria-label="search"
				>
					<SearchIcon
						className={styles.searchIcon}
						style={{ color: "rgba(153, 153, 153, 1)" }}
					/>
				</IconButton>
				<InputBase
					className={styles.searchInput}
					placeholder="请输入算子名称"
					value={keyword}
					onChange={keywordChange}
					onKeyUp={handleKeywordKeyUp}
					sx={{ fontSize: "14px" }}
				/>
			</div>
			<div className={styles.list} onScroll={(e) => handleScroll(e)}>
				{list.map((item, index) => {
					return (
						<div
							key={index}
							className={styles.li}
							draggable={true}
							onDragStart={() => onDragStart(item)}
							onDragEnd={onDragEnd}
						>
							{randerIcon()}
							<div className={styles.nameVersion}>
								<span className={styles.name}>{item.title}</span>
								<span className={styles.version}>v{item.version}</span>
							</div>
						</div>
					);
				})}
				{loading && (
					<div className={styles.loading}>
						<CircularProgress
							size={12}
							sx={{
								color: "rgba(19, 112, 255, 1)",
								marginRight: "8px",
							}}
						/>
						加载中...
					</div>
				)}
				{isLastPage && <div className={styles.loading}>已经到底了</div>}
			</div>
		</div>
	);
};

export default OperatorList;
