import _ from "lodash";
import { useCallback, useEffect, useMemo, useState } from "react";
import classNames from "classnames";

import {
	ITask,
	IParameter,
} from "../../../Project/ProjectSubmitWork/interface";
import noTemplate from "@/assets/project/noTemplate.svg";
import MyInput from "@/components/mui/MyInput";
import MyCheckBox from "@/components/mui/MyCheckBox";
import MySelect from "@/components/mui/MySelect";
import FileSelect, {
	FileSelectType,
} from "@/components/BusinessComponents/FileSelect";
import MyRadio from "@/components/mui/MyRadio";
import questionMark from "@/assets/project/questionMark.svg";
import fileSelectIcon from "@/assets/project/fileSelect.svg";
import MySwitch from "@/components/mui/MySwitch";
import Tabs from "@/components/mui/Tabs";
import { getCustomTemplateParameterCheckResult } from "../../util";
import MyTooltip from "@/components/mui/MyTooltip";

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

type IParameterSettingProps = {
	templateConfigInfo: ITask[];
	taskId: string;
	setTemplateConfigInfo: any;
};
// 页面调试数据 暂不删除
// const templateConfigInfoMock = [
// 	{
// 		id: "id",
// 		title: "title",
// 		description:
// 			"阿斯蒂芬吉林集安拉开圣诞节疯狂拉升阶段阿斯蒂芬吉林集安拉开圣诞节疯狂拉升阶段阿斯蒂芬吉林集安拉开圣诞节疯狂拉升阶段阿斯蒂芬吉林集安拉开圣诞节疯狂拉升阶段阿斯蒂芬吉林集安拉开圣诞节疯狂拉升阶段阿斯蒂芬吉林集安拉开圣诞节疯狂拉升阶段",
// 		version: "version",
// 		position: {
// 			x: 10,
// 			y: 100,
// 		},
// 		tags: ["string[]"],
// 		type: "BATCH",
// 		parentNode: "string",
// 		parameters: [
// 			{
// 				hidden: true,
// 				id: "1",
// 				name: "smi_in",
// 				required: true,
// 				defaultValue: "",
// 				domType: "input",
// 				classType: "STRING",
// 				classTypeName: "String",
// 				value: "",
// 				description: "123",
// 				language: "",
// 				languageVersion: "",
// 				tags: [],
// 				source: "string",
// 				productId: "",
// 				tasks: [],
// 				validators: [
// 					{
// 						message: "请选择smi文件作为输入",
// 						regex: "^.[s][m][i]$",
// 					},
// 				],
// 				choices: [],
// 				parameterGroup: "in",
// 			},
// 			{
// 				hidden: true,
// 				id: "2",
// 				name: "out",
// 				required: true,
// 				defaultValue: "",
// 				domType: "select",
// 				classType: "STRING",
// 				classTypeName: "String",
// 				value: "",
// 				description: "",
// 				language: "",
// 				languageVersion: "",
// 				tags: [],
// 				source: "string",
// 				productId: "",
// 				tasks: [],
// 				validators: [
// 					{
// 						message: "请选择smi文件作为输入",
// 						regex: "^.[s][m][i]$",
// 					},
// 				],
// 				choices: [],
// 				parameterGroup: "out",
// 			},
// 			{
// 				hidden: true,
// 				id: "3",
// 				name: "basis999",
// 				required: true,
// 				defaultValue: "",
// 				domType: "select",
// 				classType: "STRING",
// 				classTypeName: "String",
// 				value: "",
// 				description: "789",
// 				language: "",
// 				languageVersion: "",
// 				tags: [],
// 				source: "string",
// 				productId: "",
// 				tasks: [],
// 				validators: [
// 					{
// 						message: "请选择smi文件作为输入",
// 						regex: "^.[s][m][i]$",
// 					},
// 				],
// 				choices: [],
// 				parameterGroup: "basis",
// 			},
// 			{
// 				hidden: true,
// 				id: "4",
// 				name: "basis",
// 				required: true,
// 				defaultValue: "",
// 				domType: "select",
// 				classType: "STRING",
// 				classTypeName: "String",
// 				value: "",
// 				description: "",
// 				language: "",
// 				languageVersion: "",
// 				tags: [],
// 				source: "string",
// 				productId: "",
// 				tasks: [],
// 				validators: [
// 					{
// 						message: "请选择smi文件作为输入",
// 						regex: "^.[s][m][i]$",
// 					},
// 				],
// 				choices: [],
// 				parameterGroup: "basis",
// 			},
// 			{
// 				hidden: true,
// 				id: "5",
// 				name: "senior",
// 				required: true,
// 				defaultValue: "",
// 				domType: "checkbox",
// 				classType: "STRING",
// 				classTypeName: "String",
// 				value: "",
// 				description: "",
// 				language: "",
// 				languageVersion: "",
// 				tags: [],
// 				source: "string",
// 				productId: "",
// 				tasks: [],
// 				validators: [
// 					{
// 						message: "请选择smi文件作为输入",
// 						regex: "^.[s][m][i]$",
// 					},
// 				],
// 				choices: [
// 					{
// 						label: "123",
// 						value: "123",
// 					},
// 					{
// 						label: "456",
// 						value: "456",
// 					},
// 					{
// 						label: "789",
// 						value: "789",
// 					},
// 				],
// 				parameterGroup: "senior",
// 			},
// 			{
// 				hidden: true,
// 				id: "6",
// 				name: "hardware",
// 				required: true,
// 				defaultValue: "",
// 				domType: "radio",
// 				classType: "STRING",
// 				classTypeName: "String",
// 				value: "",
// 				description: "",
// 				language: "",
// 				languageVersion: "",
// 				tags: [],
// 				source: "string",
// 				productId: "",
// 				tasks: [],
// 				validators: [
// 					{
// 						message: "请选择smi文件作为输入",
// 						regex: "^.[s][m][i]$",
// 					},
// 				],
// 				choices: [
// 					{
// 						label: "123",
// 						value: "123",
// 					},
// 					{
// 						label: "456",
// 						value: "456",
// 					},
// 					{
// 						label: "789",
// 						value: "789",
// 					},
// 				],
// 				parameterGroup: "hardware",
// 			},
// 		],
// 		edges: [],
// 		isCheck: false,
// 		executionStatus: "Pending",
// 	},
// ];
// const taskId = "id";
const ParameterSetting = (props: IParameterSettingProps) => {
	const { templateConfigInfo, setTemplateConfigInfo, taskId } = props; // 算子大数组

	// 页面调试数据 暂不删除
	// const [templateConfigInfo, setTemplateConfigInfo] = useState<ITask[]>(
	// 	templateConfigInfoMock as ITask[]
	// );

	const [descHeight, setDescHeight] = useState(0); // 算子描述的高度  用来完成描述展开收起功能
	const [isShowAllDese, setIsShowAllDese] = useState(false); // 是否展示全部描述
	const [fileSelectOpen, setFileSelectOpen] = useState(false); // 选择输出路径的弹窗显示控制
	const [fileSelectType, setFileSelectType] = useState<FileSelectType>("path");
	const [parameterName, setParameterName] = useState(""); // 当前算子中的parameters中正在编辑饿parameter（参数）

	const div = document.getElementById("descHeight"); // 算子描述的元素（不限高）用来完成描述展开收起功能
	useEffect(() => {
		if (div) {
			setDescHeight(div.offsetHeight);
		}
	}, [div]);

	// 文件夹路线选择器弹窗
	const handleFileSelectOnClose = () => {
		setFileSelectOpen(false);
	};

	// 选中的算子详情
	const taskInfo: ITask | null = useMemo(() => {
		if (!taskId) {
			return null;
		} else {
			const randerTaskArr = templateConfigInfo.filter(
				(task) => task.id === taskId
			);
			if (randerTaskArr.length > 0) {
				return randerTaskArr[0] as ITask;
			} else {
				return null;
			}
		}
	}, [templateConfigInfo, taskId]);

	/** 通过parameter.name删除与之相关联的线 */
	const handleHiddenDeleteEdge = useCallback(
		(val: ITask[], parameterName: string) => {
			return (
				val?.length &&
				val?.map((item) => {
					if (item.id === taskId) {
						const newParameters =
							(item.parameters?.length &&
								item.parameters.map((every) => {
									if (every.name === parameterName) {
										return {
											...every,
											linked: false,
										};
									} else {
										return every;
									}
								})) ||
							[];
						return {
							...item,
							parameters: newParameters,
						};
					} else {
						const newEdges =
							(item?.edges?.length &&
								item?.edges?.filter((every) => {
									return every.targetHandle !== parameterName;
								})) ||
							[];
						return {
							...item,
							edges: newEdges,
						};
					}
				})
			);
		},
		[taskId]
	);

	// 设置parameter.hidden字段
	const handleHiddenChange = useCallback(
		(e: any, parameterName: string) => {
			let result: ITask[] = _.cloneDeep(templateConfigInfo);
			const taskIndex = result.findIndex((item) => {
				return item.id === taskId;
			});
			if (taskIndex !== -1) {
				let isCheck = true;
				result[taskIndex].parameters.forEach((parameter) => {
					if (parameter.name === parameterName) {
						parameter.hidden = !e.target.checked;
						const checkResult =
							getCustomTemplateParameterCheckResult(parameter);
						parameter.error = checkResult.error;
						parameter.helperText = checkResult.helperText;
					}
					if (getCustomTemplateParameterCheckResult(parameter).error === true) {
						isCheck = false;
					}
				});
				result[taskIndex].isCheck = isCheck;
			}
			if (e.target.checked) {
				result = handleHiddenDeleteEdge(result, parameterName) || [];
			}
			setTemplateConfigInfo(result);
		},
		[templateConfigInfo, handleHiddenDeleteEdge, setTemplateConfigInfo, taskId]
	);

	// 设置parameter.defaultValue字段
	const handleParameterChange = useCallback(
		(e: any, parameterName: string) => {
			const result: ITask[] = _.cloneDeep(templateConfigInfo);
			const taskIndex = result.findIndex((item) => {
				return item.id === taskId;
			});
			if (taskIndex !== -1) {
				let isCheck = true;
				result[taskIndex].parameters.forEach((parameter) => {
					if (parameter.name === parameterName) {
						parameter.defaultValue = e.target.value;
						const checkResult =
							getCustomTemplateParameterCheckResult(parameter);
						parameter.error = checkResult.error;
						parameter.helperText = checkResult.helperText;
					}
					if (getCustomTemplateParameterCheckResult(parameter).error === true) {
						isCheck = false;
					}
				});
				result[taskIndex].isCheck = isCheck;
			}
			setTemplateConfigInfo(result);
		},
		[templateConfigInfo, setTemplateConfigInfo, taskId]
	);

	// 文件夹路线选择确认回调
	const onFileSelectConfirm = (path: string) => {
		setFileSelectOpen(false);
		handleParameterChange(
			{
				target: {
					value: `ProjectData${path === "/" ? "" : path}`,
				},
			},
			parameterName
		);
	};

	// 渲染当个表单项
	const renderInput = useCallback(
		(parameter: IParameter) => {
			return (
				<MyTooltip title={parameter.description} placement="right">
					<div>
						{(parameter.domType || "").toLowerCase() === "file" && (
							<MyInput
								value={parameter.defaultValue || ""}
								InputProps={{
									endAdornment: (
										<img
											onClick={() => {
												if (parameter.parameterGroup === "out") {
													return;
												}
												setFileSelectType("file");
												handleOpenFileSelect(parameter.name);
											}}
											src={fileSelectIcon}
											alt=""
											className={styles.fileSelectImg}
										/>
									),
								}}
								placeholder="请选择"
								error={parameter.error || false}
								helperText={parameter.helperText}
								disabled={parameter.parameterGroup === "out"}
							></MyInput>
						)}
						{(parameter.domType || "").toLowerCase() === "path" && (
							<MyInput
								value={parameter.defaultValue || ""}
								InputProps={{
									endAdornment: (
										<img
											onClick={() => {
												if (parameter.parameterGroup === "out") {
													return;
												}
												setFileSelectType("path");
												handleOpenFileSelect(parameter.name);
											}}
											src={fileSelectIcon}
											alt=""
											className={styles.fileSelectImg}
										/>
									),
								}}
								placeholder="请选择"
								error={parameter.error || false}
								helperText={parameter.helperText}
								disabled={parameter.parameterGroup === "out"}
							></MyInput>
						)}
						{(parameter.domType || "").toLowerCase() === "dataset" && (
							<MyInput
								value={parameter.defaultValue || ""}
								InputProps={{
									endAdornment: (
										<img
											onClick={() => {
												if (parameter.parameterGroup === "out") {
													return;
												}
												setFileSelectType("dataset");
												handleOpenFileSelect(parameter.name);
											}}
											src={fileSelectIcon}
											alt=""
											className={styles.fileSelectImg}
										/>
									),
								}}
								placeholder="请选择"
								error={parameter.error || false}
								helperText={parameter.helperText}
								disabled={parameter.parameterGroup === "out"}
							></MyInput>
						)}
						{(parameter.domType || "").toLowerCase() === "input" && (
							<MyInput
								value={parameter.defaultValue || ""}
								onChange={(e: any) =>
									handleParameterChange(e, parameter.name || "")
								}
								placeholder="可输入默认值"
								error={parameter.error || false}
								helperText={parameter.helperText}
								disabled={parameter.parameterGroup === "out"}
							></MyInput>
						)}
						{(parameter.domType || "").toLowerCase() === "select" && (
							<MySelect
								value={parameter.defaultValue}
								onChange={(e: any) =>
									handleParameterChange(
										{
											target: {
												value: e,
											},
										},
										parameter.name || ""
									)
								}
								error={parameter.error || false}
								helpertext={parameter.helperText}
								options={parameter?.choices || []}
								disabled={parameter.parameterGroup === "out"}
							></MySelect>
						)}
						{(parameter.domType || "").toLowerCase() === "multipleselect" && (
							<MySelect
								value={parameter.defaultValue}
								onChange={(e: any) =>
									handleParameterChange(
										{
											target: {
												value: e,
											},
										},
										parameter.name || ""
									)
								}
								multiple={true}
								error={parameter.error || false}
								helpertext={parameter.helperText}
								options={parameter?.choices || []}
								disabled={parameter.parameterGroup === "out"}
							></MySelect>
						)}
						{(parameter.domType || "").toLowerCase() === "radio" && (
							<MyRadio
								value={parameter.defaultValue}
								onChange={(e: any) =>
									handleParameterChange(e, parameter.name || "")
								}
								options={parameter?.choices || []}
								error={parameter.error || false}
								helperText={parameter.helperText}
							></MyRadio>
						)}
						{(parameter.domType || "").toLowerCase() === "checkbox" && (
							<MyCheckBox
								value={parameter.defaultValue}
								onChange={(e: any) =>
									handleParameterChange(
										{
											target: {
												value: e,
											},
										},
										parameter.name || ""
									)
								}
								options={parameter?.choices || []}
								error={parameter.error || false}
								helperText={parameter.helperText}
							></MyCheckBox>
						)}
					</div>
				</MyTooltip>
			);
		},
		[handleParameterChange]
	);

	// 输入参数
	const inParameters: Array<IParameter> = useMemo(() => {
		if (!taskInfo) {
			return [];
		} else {
			return taskInfo.parameters.filter(
				(parameter) => parameter.parameterGroup === "in"
			);
		}
	}, [taskInfo]);

	// 输出参数
	const outParameters: Array<IParameter> = useMemo(() => {
		if (!taskInfo) {
			return [];
		} else {
			return taskInfo.parameters.filter(
				(parameter) => parameter.parameterGroup === "out"
			);
		}
	}, [taskInfo]);

	// 基础参数
	const basisParameters: Array<IParameter> = useMemo(() => {
		if (!taskInfo) {
			return [];
		} else {
			return taskInfo.parameters.filter(
				(parameter) => parameter.parameterGroup === "basis"
			);
		}
	}, [taskInfo]);

	// 高级选项
	const seniorParameters: Array<IParameter> = useMemo(() => {
		if (!taskInfo) {
			return [];
		} else {
			return taskInfo.parameters.filter(
				(parameter) => parameter.parameterGroup === "senior"
			);
		}
	}, [taskInfo]);

	// 硬件配置
	const hardwareParameters: Array<IParameter> = useMemo(() => {
		if (!taskInfo) {
			return [];
		} else {
			return taskInfo.parameters.filter(
				(parameter) => parameter.parameterGroup === "hardware"
			);
		}
	}, [taskInfo]);

	// 某种类型的参数组渲染
	const randerParameters = useCallback(
		(parameters: Array<IParameter>) => {
			return (
				<div className={styles.parameters}>
					{parameters.map((parameter, parameterIndex) => {
						return (
							<div
								className={styles.parameter}
								key={`${parameter.name}${parameterIndex}`}
							>
								<div className={styles.parameterTop}>
									<div className={styles.parameterLeft}>
										<div
											className={classNames({
												[styles.parameterName]: true,
												[styles.required]: parameter.required,
											})}
										>
											{parameter.name}
										</div>
										<div className={styles.parameterClassTypeName}>
											{parameter.classTypeName}
										</div>
									</div>
									<MySwitch
										value={!parameter.hidden}
										onChange={(e: any) =>
											handleHiddenChange(e, parameter.name || "")
										}
									></MySwitch>
								</div>
								<div className={styles.parameterContent}>
									{renderInput(parameter)}
								</div>
							</div>
						);
					})}
				</div>
			);
		},
		[renderInput, handleHiddenChange]
	);

	// 显示文件夹路径选择弹窗
	const handleOpenFileSelect = (parameterName: string = "") => {
		setParameterName(parameterName);
		setFileSelectOpen(true);
	};

	// 参数组tabs
	const paramsTabList = useMemo(() => {
		return [
			{
				label: "基础参数",
				value: "basis",
				component: randerParameters(basisParameters),
				disabled: basisParameters.length === 0,
			},
			{
				label: "高级选项",
				value: "senior",
				component: randerParameters(seniorParameters),
				disabled: seniorParameters.length === 0,
			},
			{
				label: "硬件配置",
				value: "hardware",
				component: randerParameters(hardwareParameters),
				disabled: hardwareParameters.length === 0,
			},
		];
	}, [basisParameters, seniorParameters, hardwareParameters, randerParameters]);

	// 激活的参数组tab
	const activeParamsTab = useMemo(() => {
		if (basisParameters.length !== 0) {
			return "basis";
		} else if (seniorParameters.length !== 0) {
			return "senior";
		} else if (hardwareParameters.length !== 0) {
			return "hardware";
		} else {
			return "";
		}
	}, [basisParameters, seniorParameters, hardwareParameters]);

	return (
		<div className={styles.parameterSetting}>
			{taskInfo && (
				<div className={styles.taskInfo}>
					<div className={styles.taskTitle}>{taskInfo.title || "-"}</div>
					<div className={styles.taskVersion}>
						版本：{taskInfo.version || "-"}
					</div>
					<div className={styles.taskDescriptionHeight} id="descHeight">
						{taskInfo.description || "-"}
					</div>
					<div
						className={classNames({
							[styles.taskDescriptionAll]: isShowAllDese,
							[styles.taskDescription]: !isShowAllDese,
						})}
					>
						{taskInfo.description || "-"}
						{descHeight > 60 && (
							<span
								className={styles.descButton}
								onClick={() => setIsShowAllDese(!isShowAllDese)}
							>
								{isShowAllDese ? "收起" : "展开"}
							</span>
						)}
					</div>
				</div>
			)}
			{inParameters.length > 0 && (
				<div className={styles.inOutBox}>
					<div className={styles.paramsTitle}>
						输入
						<MyTooltip
							title="当某个输入项为启用状态时，代表该输入将由模板使用者在使用的时候填写赋值；当为关闭状态时，代表该输入不需要使用者来填写赋值，而是将其它流程的结果传入。"
							placement="right"
						>
							<img
								className={styles.paramsTitleDesc}
								src={questionMark}
								alt=""
							/>
						</MyTooltip>
					</div>
					<div className={styles.paramsList}>
						{inParameters.map((parameter, index) => {
							return (
								<div
									className={styles.inOutParameterBox}
									key={`${parameter.name}${index}`}
								>
									<div className={styles.inOutParameterTop}>
										<div className={styles.inOutParameterleft}>
											<div
												className={classNames({
													[styles.inOutParameterName]: true,
													[styles.required]: parameter.required,
												})}
											>
												{parameter.name}
											</div>
											<div className={styles.inOutParameterdataType}>
												{parameter.classTypeName}
											</div>
										</div>
										<div className={styles.inOutParameterRight}>
											<MySwitch
												value={!parameter.hidden}
												onChange={(e: any) =>
													handleHiddenChange(e, parameter.name || "")
												}
											></MySwitch>
										</div>
									</div>
									{parameter.error && parameter.helperText && (
										<div className={styles.inOutParameterHelperText}>
											{parameter.helperText}
										</div>
									)}
									{/* {renderInput(parameter)} */}
								</div>
							);
						})}
					</div>
				</div>
			)}
			{outParameters.length > 0 && (
				<div className={styles.inOutBox}>
					<div className={styles.paramsTitle}>输出</div>
					<div className={styles.paramsList}>
						{outParameters.map((parameter, index) => {
							return (
								<div
									className={styles.inOutParameterBox}
									key={`${parameter.name}${index}`}
								>
									<div className={styles.inOutParameterTop}>
										<div className={styles.inOutParameterleft}>
											<div
												className={classNames({
													[styles.inOutParameterName]: true,
													[styles.required]: parameter.required,
												})}
											>
												{parameter.name}
											</div>
											<div className={styles.inOutParameterdataType}>
												{parameter.classTypeName}
											</div>
										</div>
										<div className={styles.inOutParameterRight}></div>
									</div>
									{renderInput(parameter)}
								</div>
							);
						})}
					</div>
				</div>
			)}
			{taskInfo && (
				<div className={styles.paramsGroup}>
					<div className={styles.paramsTitle}>
						参数组
						<MyTooltip
							title="当某个参数项为启用状态时，代表该参数将由模板使用者在使用的时候填写赋值；当为关闭状态时，代表该参数不需要使用者来填写赋值。"
							placement="right"
						>
							<img
								className={styles.paramsTitleDesc}
								src={questionMark}
								alt=""
							/>
						</MyTooltip>
					</div>
					<Tabs
						tabList={paramsTabList}
						defaultValue={activeParamsTab}
						allowNullValue={true}
						tabPanelSx={{ padding: "7px 0" }}
					/>
				</div>
			)}
			{!taskInfo && (
				<div className={styles.noData}>
					<img src={noTemplate} alt="" className={styles.noDataImg} />
					<span className={styles.noDataText}>选中任意算子进行参数设置</span>
				</div>
			)}
			{fileSelectOpen && (
				<FileSelect
					onClose={handleFileSelectOnClose}
					open={fileSelectOpen}
					onConfirm={onFileSelectConfirm}
					type={fileSelectType}
				/>
			)}
		</div>
	);
};

export default ParameterSetting;
