/*
 * @Author: 吴永生 15770852798@163.com
 * @Date: 2022-10-18 16:12:55
 * @LastEditors: 吴永生 15770852798@163.com
 * @LastEditTime: 2022-10-24 13:40:27
 * @FilePath: /bkunyun/src/views/ResourceCenter/UserResources/WorkflowOperator/components/AddOperator/index.tsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import { useEffect, useState, useCallback, useMemo } from "react";
import classNames from "classnames";
import { observer } from "mobx-react";
import { Base64 } from "js-base64";
import _ from "lodash";

import MyInput from "@/components/mui/MyInput";
import MySelect from "@/components/mui/MySelect";
import MyButton from "@/components/mui/MyButton";
import SwitchBatchFolw from "@/views/ResourceCenter/components/SwitchBatchFolw";
import Code from "@/components/CommonComponents/Code";
import RadioGroupOfButtonStyle from "@/components/CommonComponents/RadioGroupOfButtonStyle";
import { ITask } from "@/views/Project/ProjectSubmitWork/interface";
import BatchOperatorFlow from "@/views/Project/components/Flow/components/BatchOperatorFlow";
import OperatorList from "@/views/CustomOperator/components/OperatorList";
import FormItemBox from "@/components/mui/FormItemBox";
import { useStores } from "@/store";
import useMyRequest from "@/hooks/useMyRequest";
import { getActorEnvOptions, saveOperator } from "@/api/resourceCenter";
import { IOperatorAddFormData } from "../../interface";
import { checkFormData, checkParamsConfig, initCode } from "./utils";

import style from "./index.module.css";
import { useMessage } from "@/components/MySnackbar";
interface IAddOperator {
	pageType: string;
	setPageType: (val: string) => void;
}

type IBuildType = "ENVIRONMENT" | "OPERATOR";

const AddOperator = observer((props: IAddOperator) => {
	const { setPageType } = props;
	const Message = useMessage();

	/** 创建类型 BATCH - 批算子;  FLOW - 流算子*/
	const [taskType, setTaskType] = useState<"BATCH" | "FLOW">("BATCH");
	/** 创建类型 ENVIRONMENT - 基于环境;  OPERATOR - 基于算子*/
	const [batchBuildType, setBatchBuildType] =
		useState<IBuildType>("ENVIRONMENT");
	/** 算子数组 */
	const [operatorList, setOperatorList] = useState<ITask[]>([]);
	/** 流程编排 算子是否选中 */
	const [inputActive, setInputActive] = useState(false);
	/** 产品store */
	const { productListStore } = useStores();
	/** 应用环境下拉 */
	const [actorEnvOptions, setActorEnvOptions] = useState([]);
	/** 参数配置 */
	const [code, setCode] = useState(JSON.stringify(initCode, null, "\t"));
	/** 运行脚本 */
	const [command, setCommand] = useState<string>("");

	/** 表单数据 */
	const [formData, setFormData] = useState<IOperatorAddFormData>({});
	/** 表单数据修改 */
	const [formErrors, setFormErrors] = useState<IOperatorAddFormData>({});

	const buildTypeList = useMemo(() => {
		return [
			{ value: "ENVIRONMENT", label: "基于应用环境" },
			{ value: "OPERATOR", label: "基于流式算子" },
		];
	}, []);

	/** 表单数据 */
	const changeFormData = useCallback(
		(val: IOperatorAddFormData) => {
			setFormData({ ...formData, ...val });
		},
		[formData]
	);

	const paramsConfigBlur = () => {
		if (code === "") return;
		let result;
		try {
			result = JSON.stringify(JSON.parse(code), null, "\t");
			if (typeof result === "string") {
				setCode(result);
				const checkErrorArr = checkParamsConfig(result);
				if (checkErrorArr.length) {
					Message.error("参数配置不正确！");
					setFormErrors({
						...formErrors,
						...{ parameters: "参数配置不正确！" },
					});

					const codeDom = document.getElementById("paramsConfig");
					const all = codeDom?.getElementsByClassName("cm-line");
					const allArr = Array.prototype.slice.call(all);
					for (let x = 0; x < allArr?.length; x++) {
						const a = `${allArr[x]?.innerHTML}`
							.replace(/"/g, "")
							.replace(/,/g, "")
							.replace(/\t/g, "");
						if (checkErrorArr.includes(a)) {
							setTimeout(() => {
								allArr[x].style =
									"text-decoration: wavy underline; text-decoration-color: #ff4e4e;";
							}, 500);
						}
					}
				} else {
					const newFormErrors = _.cloneDeep(formErrors);
					delete newFormErrors.parameters;
					setFormErrors(newFormErrors);
				}
			}
		} catch (error) {
			Message.error("JSON格式不正确！");
			console.log("JSON格式不正确！");
		}
	};

	/** 获取应用环境下拉 */
	const { run: fetchActorEnvOptions } = useMyRequest(getActorEnvOptions, {
		onSuccess: (res: any) => {
			if (res.message === "success") {
				const newActorEnvOptions =
					res?.data?.map((item: any) => {
						return { label: item.title, value: item.id };
					}) || [];
				setActorEnvOptions(newActorEnvOptions);
			}
		},
	});

	useEffect(() => {
		fetchActorEnvOptions({ type: taskType });
	}, [fetchActorEnvOptions, taskType]);

	/** 切换类型 */
	const handleRadio = (val: IBuildType) => {
		setBatchBuildType(val);
	};

	const handleSubmit = useCallback(() => {
		const resultErrors = checkFormData(formData, taskType);
		formErrors?.parameters
			? setFormErrors({ ...resultErrors, parameters: formErrors.parameters })
			: setFormErrors({ ...resultErrors });
		if (Object.getOwnPropertyNames(resultErrors)?.length) return;
		let newParameters = [];
		try {
			newParameters = JSON.parse(code);
		} catch (err) {
			console.log(err);
		}

		const params = {
			...formData,
			command: Base64.encode(command),
			parameters: newParameters,
			type: taskType,
		};
		saveOperator(params).then((res) => {
			console.log(res, "333");
		});
	}, [code, command, formData, formErrors, taskType]);

	return (
		<div className={style.addOperatorBox}>
			<div className={style.left}>
				<SwitchBatchFolw
					active={taskType}
					setActive={setTaskType}
					goBack={() => setPageType("")}
				></SwitchBatchFolw>
			</div>
			<div className={style.right}>
				<div className={style.title}>
					{taskType === "BATCH" ? "批式算子信息" : "流式算子信息"}
				</div>
				<div
					style={{
						paddingBottom: batchBuildType === "ENVIRONMENT" ? "20px" : "2px",
					}}
				>
					<RadioGroupOfButtonStyle
						RadiosBoxStyle={{ width: 236 }}
						value={batchBuildType}
						radioOptions={buildTypeList}
						handleRadio={handleRadio}
					/>
				</div>
				<div className={style.content}>
					<div
						className={classNames({
							[style.form]: batchBuildType === "ENVIRONMENT",
							[style.newForm]: batchBuildType !== "ENVIRONMENT",
						})}
					>
						<FormItemBox
							label="算子名称"
							labelClassName={style.labelClassName}
							className={classNames({
								[style.operatorFormItem]: formErrors?.title,
							})}
							itemFlex="column"
							errorMessage={formErrors?.title || ""}
							require
						>
							<MyInput
								helperText={
									formErrors?.title ? "" : "15字符以内，仅限字母、数字、中文"
								}
								placeholder="请输入算子名称"
								value={formData?.title}
								onChange={(e) => {
									if (e.target.value?.length > 15) return;
									changeFormData({ title: e.target.value });
								}}
							/>
						</FormItemBox>
						<FormItemBox
							label="算子版本"
							labelClassName={style.labelClassName}
							className={style.operatorFormItem}
							itemFlex="column"
							errorMessage={formErrors?.version || ""}
							require
						>
							<MyInput
								value={formData?.version}
								onChange={(e) => {
									changeFormData({ version: e.target.value });
								}}
							/>
						</FormItemBox>
						<FormItemBox
							label="所属产品"
							labelClassName={style.labelClassName}
							errorMessage={formErrors?.productId || ""}
							className={classNames({
								[style.operatorFormItem]: batchBuildType === "ENVIRONMENT",
							})}
							itemFlex="column"
							require
						>
							<MySelect
								fullWidth
								options={productListStore?.productList || []}
								value={formData?.productId}
								onChange={(e) => {
									changeFormData({ productId: e });
								}}
							/>
						</FormItemBox>
						{batchBuildType === "ENVIRONMENT" ? (
							<FormItemBox
								label="应用环境"
								labelClassName={style.labelClassName}
								className={style.operatorFormItem}
								errorMessage={formErrors?.envId || ""}
								itemFlex="column"
								require
							>
								<MySelect
									fullWidth
									options={actorEnvOptions || []}
									value={formData?.envId}
									onChange={(e) => {
										changeFormData({ envId: e });
									}}
								/>
							</FormItemBox>
						) : null}
						{batchBuildType === "ENVIRONMENT" ? (
							<FormItemBox
								label="描述"
								labelClassName={style.labelClassName}
								itemFlex="column"
								errorMessage={formErrors?.description || ""}
							>
								<MyInput
									multiline
									rows={4}
									placeholder="请输入算子描述"
									value={formData?.description}
									onChange={(e) => {
										changeFormData({ description: e.target.value });
									}}
								/>
							</FormItemBox>
						) : null}
					</div>

					{batchBuildType === "ENVIRONMENT" ? (
						<div className={style.codeBox}>
							<div className={style.codeTitle}>参数配置</div>
							<div className={style.code}>
								<Code
									id="paramsConfig"
									value={code}
									// placeholder="dd"
									onChange={(e: string, viewUpdate: any) => {
										setCode(e);
									}}
									onBlur={paramsConfigBlur}
									height="535px"
									width="600"
									style={{ flex: 1 }}
								/>
							</div>
						</div>
					) : (
						<div className={style.descBox}>
							<FormItemBox
								label="描述"
								labelClassName={style.labelClassName}
								className={style.operatorFormItem}
								itemFlex="column"
								errorMessage={formErrors?.description || ""}
							>
								<MyInput
									style={{ width: "420px" }}
									multiline
									rows={10}
									placeholder="请输入算子描述"
									value={formData?.description}
									onChange={(e) => {
										changeFormData({ description: e.target.value });
									}}
								/>
							</FormItemBox>
						</div>
					)}
				</div>
				<div className={style.parameterConfigBox}>
					<div className={style.codeTitle}>
						{batchBuildType === "ENVIRONMENT" ? "运行脚本" : "流程编排"}
					</div>
					{batchBuildType === "ENVIRONMENT" ? (
						<div className={style.code}>
							<Code
								value={command}
								onChange={(e: string) => setCommand(e)}
								height="350px"
							/>
						</div>
					) : (
						<div
							id="customOperatorFlow"
							style={{ position: "relative", height: 400 }}
						>
							<OperatorList
								operatorList={operatorList}
								setOperatorList={setOperatorList}
								setInputActive={setInputActive}
							/>
							<BatchOperatorFlow
								tasks={operatorList}
								setTasks={setOperatorList}
								type="edit"
								// onFlowNodeClick={handleNodeClick}
								flowNodeDraggable={true}
								ListenState={!inputActive}
								showVersion={true}
								showControls={false}
							/>
						</div>
					)}
				</div>
				<div className={style.buttonBox}>
					<MyButton text="开始构建" onClick={handleSubmit} />
				</div>
			</div>
		</div>
	);
});
export default AddOperator;
