import { OutlinedInput } from "@mui/material";
import SearchIcon from "@mui/icons-material/Search";
import classNames from "classnames";
import { useCallback, useEffect, useState } from "react";
import { observer } from "mobx-react-lite";
import { toJS } from "mobx";
import cloneDeep from "lodash/cloneDeep";

import { IOperatorItemProps, IOperatorListProps } from "./interface";
import { ITask } from "@/views/Project/ProjectSubmitWork/interface";
import useMyRequest from "@/hooks/useMyRequest";
import { IResponse } from "@/api/http";
import { fetchOperatorList } from "@/api/workbench_api";
import { useStores } from "@/store";
import noTemplate from "@/assets/project/noTemplate.svg";

import styles from "./index.module.css";

/*
 * @Author: 吴永生#A02208 yongsheng.wu@wholion.com
 * @Date: 2022-07-06 15:16:01
 * @LastEditors: 吴永生#A02208 yongsheng.wu@wholion.com
 * @LastEditTime: 2022-07-07 15:48:12
 * @FilePath: /bkunyun/src/views/WorkFlowEdit/components/OperatorList/index.tsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

let count = 1;

const OperatorItem = (props: IOperatorItemProps) => {
	const {
		info: { title, description, tags, version },
		setTemplateConfigInfo,
		templateConfigInfo,
		operatorListData,
		info,
	} = props;
	const [isDragStyle, setIsDragStyle] = useState<boolean>(false);

	/** 拖拽开始 */
	const onDragStart = useCallback(() => {
		setIsDragStyle(true);
		count++;
	}, []);

	/** 通过id查找相对的批流数组 */
	const getBatchFlowArr = useCallback(
		(id: string) => {
			const newVal = operatorListData.filter((item) => {
				return item.id === id || item.parentNode === id;
			});
			return newVal;
		},
		[operatorListData]
	);

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

	/** 拖拽结束 */
	const onDragEnd = useCallback(
		(e: React.DragEvent<HTMLDivElement>) => {
			const dom = document.getElementById("workFlowEditRight");
			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 batchFlowArr = getBatchFlowArr(info.id);
				const newBatchFlowArr = getCopyBatchFlowArr(
					batchFlowArr,
					clientX - upperLeftPointX,
					clientY - upperLeftPointY
				);
				const newVal = cloneDeep(templateConfigInfo);
				newVal.push(...newBatchFlowArr);
				setTemplateConfigInfo(newVal);
			}
			setIsDragStyle(false);
		},
		[
			getBatchFlowArr,
			getCopyBatchFlowArr,
			info.id,
			setTemplateConfigInfo,
			templateConfigInfo,
		]
	);

	return (
		<div
			className={classNames({
				[styles.operatorItemBox]: true,
				[styles.dragBox]: isDragStyle,
			})}
			draggable={true}
			onDragStart={onDragStart}
			onDragEnd={onDragEnd}
		>
			<h2 className={styles.operatorItemTitle}>{title}</h2>
			<div className={styles.operatorItemText}>{description}</div>
			<div className={styles.footerBox}>
				{tags?.map((item: string) => {
					return (
						<span
							key={item}
							className={styles.labelBox}
							style={{
								background: true ? "#EBF3FF" : "#E3FAEC",
								color: true ? "#1370FF" : "#02AB83",
							}}
						>
							{item}
						</span>
					);
				})}
				<span className={styles.versionBox}>{version}</span>
			</div>
		</div>
	);
};

const OperatorList = observer((props: IOperatorListProps) => {
	const { currentProjectStore } = useStores();
	const productId = toJS(currentProjectStore.currentProductInfo.id);
	const { templateConfigInfo, setTemplateConfigInfo, showCustomOperator } =
		props;
	const [operatorListData, setOperatorListData] = useState<ITask[]>([]);
	const [keyword, setKeyword] = useState<string>("");

	// 取消作业
	const { run } = useMyRequest(fetchOperatorList, {
		onSuccess: (res: IResponse<any>) => {
			setOperatorListData(res?.data || []);
		},
	});

	useEffect(() => {
		if (!showCustomOperator) {
			run({
				owner: "root",
				productId: productId as string,
			});
		}
	}, [productId, run, showCustomOperator]);

	/** 处理回车键 */
	const handleEnterCode = (e: React.KeyboardEvent<HTMLInputElement>) => {
		if (e.keyCode === 13) {
			getOperatorList();
		}
	};

	const getOperatorList = useCallback(() => {
		run({
			owner: "root",
			productId: productId as string,
			keyword,
		});
	}, [run, keyword, productId]);

	return (
		<div className={styles.operatorListBox}>
			<div className={styles.searchBox}>
				<OutlinedInput
					onChange={(e) => {
						if (e.target.value?.length > 30) return;
						setKeyword(e.target.value);
					}}
					value={keyword}
					placeholder="输入关键词搜索"
					onKeyUp={handleEnterCode}
					size="small"
					sx={{ height: 32, width: "100%" }}
					endAdornment={<SearchIcon style={{ color: "#8A9099" }} />}
				/>
			</div>
			<div className={styles.listBox}>
				{operatorListData.filter((item) => item.type === "BATCH")?.length ? (
					operatorListData
						.filter((item) => item.type === "BATCH")
						.map((item) => {
							return (
								<OperatorItem
									key={item.id}
									info={item}
									setOperatorListData={setOperatorListData}
									operatorListData={operatorListData}
									templateConfigInfo={templateConfigInfo}
									setTemplateConfigInfo={setTemplateConfigInfo}
								/>
							);
						})
				) : (
					<div className={styles.noData}>
						<img src={noTemplate} alt="" className={styles.noDataImg} />
						<span className={styles.noDataText}>没有找到相关算子</span>
					</div>
				)}
			</div>
		</div>
	);
});

export default OperatorList;
