/*
 * @Author: 吴永生#A02208 yongsheng.wu@wholion.com
 * @Date: 2022-05-31 10:18:13
 * @LastEditors: 吴永生 15770852798@163.com
 * @LastEditTime: 2022-07-28 18:32:03
 * @FilePath: /bkunyun/src/views/Project/ProjectSetting/index.tsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import React, { memo, useEffect, useMemo, useState } from "react";

import style from "./index.module.css";
import useMyRequest from "@/hooks/useMyRequest";
import {
	getProject,
	hpczone,
	updateProject,
	deleteProject,
} from "@/api/project_api";
import { useStores } from "@/store";
import { toJS } from "mobx";
import { observer } from "mobx-react-lite";
import InformationDisplay from "@/components/CommonComponents/InformationDisplay";
import classnames from "classnames";
import InputAdornment from "@mui/material/InputAdornment";
import { useMessage } from "@/components/MySnackbar";
import Loading from "@/views/Loading";
import MyDialog from "@/components/mui/MyDialog";
import { getProjectList } from "../../project";
import { checkIsNumberLetterChinese } from "@/utils/util";
import MyButton from "@/components/mui/MyButton";
import MySelect, { optionsTransform } from "@/components/mui/MySelect";
import MyInput from "@/components/mui/MyInput";

type zoneIdOption = {
	id: string;
	name: string;
};

const BaseInfo = observer(() => {
	const message = useMessage();
	const { currentProjectStore } = useStores();
	const fileToken = toJS(currentProjectStore.currentProjectInfo.filetoken);
	const productId = toJS(currentProjectStore.currentProductInfo.id); // 产品ID
	const [projectInfo, setProjectInfo] = useState<any>({});
	const [deleteProjectName, setDeleteProjectName] = useState("");
	const [nameCheck, setNameCheck] = useState({
		error: false,
		help: "",
	});
	const [budgetCheck, setBudgetCheck] = useState({
		error: false,
		help: "",
	});
	const currentUserName = JSON.parse(
		localStorage.getItem("userInfo") || "{}"
	).name;
	// 弹窗显示控制
	const [dialogOpen, setDialogOpen] = useState(false);

	// 打开弹窗时重置表单
	useEffect(() => {
		if (dialogOpen) {
			setDeleteProjectName("");
		}
	}, [dialogOpen]);
	// 是否拥有编辑权限
	const hasEditAuth = useMemo(() => {
		if (!currentUserName) {
			return false;
		} else if (!projectInfo.members) {
			return false;
		} else {
			return projectInfo.members.some((item: any) => {
				return (
					item.username === currentUserName && item.projectRole === "OWNER"
				);
			});
		}
	}, [currentUserName, projectInfo]);
	const { run, loading } = useMyRequest(getProject, {
		onSuccess: (result: any) => {
			setProjectInfo({
				...result.data,
				projectBudget: result.data.projectBudget.toFixed(2),
			});
		},
	});
	useEffect(() => {
		run({
			id: currentProjectStore.currentProjectInfo.id as string,
		});
	}, [currentProjectStore.currentProjectInfo.id, run]);
	const [zoneIdMap, setZoneIdMap] = useState<Map<string, string>>(new Map());
	const [zoneIdOptions, setZoneIdOptions] = useState<Array<zoneIdOption>>([]);

	// 获取计算区信息
	const { run: getZone } = useMyRequest(hpczone, {
		onSuccess: (result: any) => {
			setZoneIdOptions(result.data);
			let zoneMap: Map<string, string> = new Map();
			result.data.forEach((item: zoneIdOption) => {
				zoneMap.set(item.id, item.name);
			});
			setZoneIdMap(zoneMap);
		},
	});

	useEffect(() => {
		getZone();
	}, [getZone]);

	// 项目信息展示数据转换
	const infoList = useMemo(() => {
		return [
			{
				label: "项目名称：",
				value: projectInfo.name,
			},
			{
				label: "项目描述：",
				value: projectInfo.desc,
			},
			{
				label: "计算区：",
				value: zoneIdMap.get(projectInfo.zoneId) || projectInfo.zoneId,
			},
			{
				label: "创建人：",
				value: projectInfo.owner,
			},
			{
				label: "项目预算：",
				value: projectInfo.projectBudget,
			},
			{
				label: "扣费账号：",
				value: projectInfo.tenantUser,
			},
		];
	}, [projectInfo, zoneIdMap]);

	const checkName = (name: string, showMessage = false) => {
		let help = "";
		if (name) {
			if (name.length > 30) {
				help = "格式不正确，必须在30字符以内，仅限大小写字母、数字、中文";
				setNameCheck({
					error: true,
					help,
				});
				showMessage && message.error(help);
				return false;
			} else if (checkIsNumberLetterChinese(name)) {
				setNameCheck({
					error: false,
					help: "",
				});
				return true;
			} else {
				help = "格式不正确，必须在30字符以内，仅限大小写字母、数字、中文";
				setNameCheck({
					error: true,
					help,
				});
				showMessage && message.error(help);
				return false;
			}
		} else {
			help = "项目名称不能为空";
			setNameCheck({
				error: true,
				help,
			});
			showMessage && message.error(help);
			return false;
		}
	};

	const nameChange = (e: any) => {
		setProjectInfo({
			...projectInfo,
			name: e.target.value,
		});
		checkName(e.target.value);
	};

	const descChange = (e: any) => {
		if (e.target.value.length <= 100) {
			setProjectInfo({
				...projectInfo,
				desc: e.target.value,
			});
		}
	};

	const checkBudget = (budget: string, showMessage = false) => {
		let help = "";
		if (budget.indexOf(" ") !== -1) {
			help = "格式错误，请输入0~10000000之间的数值，结果最高保留两位小数。";
			setBudgetCheck({
				error: true,
				help,
			});
			showMessage && message.error(help);
			return false;
		} else if (budget) {
			if (
				isNaN(Number(budget)) ||
				Number(budget) > 10000000 ||
				Number(budget) < 0
			) {
				help = "格式错误，请输入0~10000000之间的数值，结果最高保留两位小数。";
				setBudgetCheck({
					error: true,
					help,
				});
				showMessage && message.error(help);
				return false;
			} else {
				setBudgetCheck({
					error: false,
					help: "",
				});
				return true;
			}
		} else {
			help = "格式错误，请输入0~10000000之间的数值，结果最高保留两位小数。";
			setBudgetCheck({
				error: true,
				help,
			});
			showMessage && message.error(help);
			return false;
		}
	};

	const budgetChange = (e: any) => {
		setProjectInfo({
			...projectInfo,
			projectBudget: e.target.value,
		});
		checkBudget(e.target.value);
	};

	const budgetBlur = (e: any) => {
		if (e.target.value.indexOf(" ") === -1 && e.target.value) {
			setProjectInfo({
				...projectInfo,
				projectBudget:
					Number(e.target.value) || Number(e.target.value) === 0
						? Number(e.target.value).toFixed(2)
						: e.target.value,
			});
		}
	};

	const { run: updateProjectRun, loading: updateLoading } = useMyRequest(
		updateProject,
		{
			onSuccess: async (result: any) => {
				message.success("修改成功");
				const projectList = await getProjectList(productId);
				currentProjectStore.setProjectList(projectList);
				projectInfo.filetoken = fileToken;
				currentProjectStore.changeProject(projectInfo);
			},
		}
	);

	// 修改项目
	const handleClickUpdate = () => {
		if (
			checkName(projectInfo.name, true) &&
			checkBudget(projectInfo.projectBudget, true)
		) {
			updateProjectRun({ ...projectInfo, product: `${productId || "cadd"}` });
		} else {
			return;
		}
	};

	const { run: deleteProjectRun } = useMyRequest(deleteProject, {
		onSuccess: async (result: any) => {
			message.success("删除成功");
			setDialogOpen(false);
			const projectList = await getProjectList(productId);
			currentProjectStore.setProjectList(projectList);
			// 项目删完了
			currentProjectStore.changeProject({});
			localStorage.setItem("fileServerEndPoint", "");
			setProjectInfo({});
		},
	});

	const deleteProjectNameChange = (e: any) => {
		setDeleteProjectName(e.target.value);
	};

	// 删除项目
	const handleSubmitDelete = () => {
		if (
			deleteProjectName === toJS(currentProjectStore.currentProjectInfo.name)
		) {
			deleteProjectRun({ id: projectInfo.id });
		} else {
			message.error("项目名称不匹配");
		}
	};

	if (loading) {
		return (
			<div className={style.loadingBox}>
				<Loading />
			</div>
		);
	} else if (!hasEditAuth) {
		return <InformationDisplay infoList={infoList} />;
	} else {
		return (
			<div className={style.projectInfoList}>
				<div className={style.projectInfoListLi}>
					<div
						className={classnames({
							[style.projectInfoListLiLabel]: true,
							[style.projectInfoName]: true,
						})}
					>
						项目名称
					</div>

					<MyInput
						required
						error={nameCheck.error}
						id="name"
						variant="outlined"
						value={projectInfo.name}
						onChange={nameChange}
						helperText={nameCheck.help}
						style={{ width: "560px" }}
					/>
				</div>
				<div className={style.projectInfoListLi}>
					<div className={style.projectInfoListLiLabel}>项目描述</div>
					<div
						className={classnames({
							[style.projectInfoTextarea]: true,
						})}
					>
						<MyInput
							value={projectInfo.desc}
							id="desc"
							placeholder="项目描述限制100字以内"
							onChange={descChange}
							multiline
							rows={4}
						/>
						<span
							style={{
								fontSize: "14px",
								position: "absolute",
								top: "96px",
								right: "12px",
								color: projectInfo.desc.length >= 100 ? "#d32f2f" : "#C2C6CC",
							}}
						>
							{projectInfo.desc.length}/100
						</span>
					</div>
				</div>
				<div className={style.projectInfoListLi}>
					<div className={style.projectInfoListLiLabel}>计算区</div>
					<MySelect
						value={projectInfo.zoneId}
						disabled
						options={optionsTransform(zoneIdOptions, "name", "id")}
						sx={{ width: "560px" }}
					></MySelect>
				</div>
				<div className={style.projectInfoListLi}>
					<div className={style.projectInfoListLiLabel}>创建人</div>
					<MyInput
						value={projectInfo.owner}
						disabled
						style={{ width: "560px" }}
					/>
				</div>
				<div className={style.projectInfoListLi}>
					<div className={style.projectInfoListLiLabel}>项目预算</div>
					<MyInput
						required
						error={budgetCheck.error}
						disabled={currentUserName !== projectInfo.tenantUser}
						variant="outlined"
						placeholder={projectInfo.projectBudget}
						onChange={budgetChange}
						onBlur={budgetBlur}
						helperText={budgetCheck.help}
						style={{ width: "560px" }}
						InputProps={{
							startAdornment: (
								<InputAdornment position="start">¥</InputAdornment>
							),
						}}
						sx={{
							"& .MuiOutlinedInput-input": {
								padding: "6.5px 2px",
							},
							"& .MuiTypography-root": {
								fontSize: "14px",
							},
						}}
					/>
				</div>
				<div className={style.projectInfoListLi}>
					<div className={style.projectInfoListLiLabel}>扣费账号</div>
					<MyInput
						value={projectInfo.tenantUser}
						disabled
						style={{ width: "560px" }}
					/>
				</div>
				<div className={style.projectInfoListLi}>
					<MyButton
						variant="contained"
						onClick={handleClickUpdate}
						loading={updateLoading}
						text="保存修改"
					/>
				</div>
				<div className={style.projectInfoListLi}>
					<div
						className={style.projectInfoListLiLabel}
						style={{ paddingTop: "12px" }}
					>
						删除项目
					</div>
					<div className={style.projectInfoListLiText}>
						删除项目将删除其存储的数据和所有相关资源，并且已删除的项目无法恢复！请谨慎操作！
					</div>
					<MyButton
						text="删除项目"
						variant="outlined"
						onClick={() => setDialogOpen(true)}
						color="error"
					/>
				</div>
				<MyDialog
					open={dialogOpen}
					onConfirm={handleSubmitDelete}
					onClose={() => setDialogOpen(false)}
					title="删除项目"
					okColor="error"
				>
					<div className={style.deleteBox}>
						<div className={style.deleteText1}>
							删除项目会导致数据丢失，已删除的项目将无法恢复。
						</div>
						<div className={style.deleteText3}>
							请输入“
							<span className={style.deleteProjectName}>
								{currentProjectStore.currentProjectInfo.name}
							</span>
							”以确认此操作。
						</div>
						<input
							value={deleteProjectName}
							className={style.deleteProjectInput}
							onChange={deleteProjectNameChange}
							maxLength={30}
							placeholder="请输入项目名称"
						></input>
					</div>
				</MyDialog>
			</div>
		);
	}
});

export default memo(BaseInfo);
