import MyInput from "@/components/mui/MyInput";
import MyDialog from "@/components/mui/MyDialog";
import RadioGroupOfButtonStyle from "@/components/CommonComponents/RadioGroupOfButtonStyle";
import style from "./index.module.css";
import MyTable from "@/components/mui/MyTableNew";
import MyMenu from "@/components/mui/MyMenu";
import cloneDeep from "lodash/cloneDeep";
import { useMessage } from "@/components/MySnackbar";
import { useEffect, useMemo, useState } from "react";

export type IQueueLi = {
	name: string;
	picUrl: string;
	cpuName: string;
	gpuName: string;
	gpuNum: number; // 卡数
	coreNum: number;
	memory: number;
	total: number;
	partition: string;
	enabled: boolean;
};

type IQueueSelectProps = {
	value: string;
	onChange: any;
	originalCpuList: Array<IQueueLi>;
	originalGpuList: Array<IQueueLi>;
	error?: boolean;
	helperText?: string;
	disabled?: boolean;
	cpuLoading?: boolean;
	gpuLoading?: boolean;
};

type IMemoryLi = {
	memory: number;
	total: number;
	partition: string;
};

export type IShowCPULi = {
	name: string;
	picUrl: string;
	cpuName: string;
	coreNum: number;
	partition: string;
	enabled: boolean;
	memoryList: Array<IMemoryLi>;
};

const queueTypes = [
	{
		label: "CPU",
		value: "CPU",
	},
	{
		label: "GPU",
		value: "GPU",
	},
];

const QueueSelect = (props: IQueueSelectProps) => {
	const {
		value,
		onChange,
		originalCpuList,
		originalGpuList,
		error,
		helperText,
		disabled,
		cpuLoading = false,
		gpuLoading = false,
	} = props;
	// 队列列表由外面传入的设计是考虑到一个表单可能有多次队列选择，  请求队列接口在表单页面完成可以减少请求
	const Message = useMessage();
	const [activePartition, setActivePartition] = useState("");
	const [open, setOpen] = useState(false);
	const [queueType, setQueueType] = useState("CPU");
	const [showCpuList, setShowCpuList] = useState<Array<IShowCPULi>>([]);
	const handleOpen = () => {
		setOpen(true);
	};

	// 队列partition和前端展示的队列信息的映射关系
	const idInfoMap = useMemo(() => {
		return [
			...originalCpuList.map((item) => ({
				partition: item.partition,
				title: `${item.name}/${item.coreNum}核${item.coreNum * item.memory}G/${
					item.coreNum
				}总核心数`,
				total: item.total,
			})),
			...originalGpuList.map((item) => ({
				partition: item.partition,
				title: `${item.name}/${item.gpuNum}卡${item.coreNum}核${item.memory}G/${item.gpuNum}总卡数`,
				total: item.total,
			})),
		];
	}, [originalCpuList, originalGpuList]);

	const cpuHeadCells = [
		{
			id: "type",
			label: "类型",
			width: 510,
		},
		{
			id: "coreNumRender",
			label: "节点核数",
			width: 180,
		},
		{
			id: "memoryRender",
			label: "设置内存配比",
			width: 150,
		},
	];

	const gpuHeadCells = [
		{
			id: "type",
			label: "类型",
			width: 510,
		},
		{
			id: "gpuNumRender",
			label: "节点卡数",
			width: 100,
		},
		{
			id: "coreNumRender",
			label: "节点核数",
			width: 100,
		},
		{
			id: "gpuMemoryRender",
			label: "节点内存容量",
			width: 100,
		},
	];

	// 有初始值的话显示初始值
	useEffect(() => {
		let resultList: Array<IShowCPULi> = [];
		originalCpuList.forEach((item) => {
			const targetIndex = resultList.findIndex((resultLi) => {
				return resultLi.name === item.name;
			});
			if (targetIndex === -1) {
				resultList.push({
					name: item.name,
					picUrl: item.picUrl,
					cpuName: item.cpuName,
					coreNum: item.coreNum,
					partition: item.partition,
					enabled: item.enabled,
					memoryList: [
						{
							memory: item.memory,
							total: item.total,
							partition: item.partition,
						},
					],
				});
			} else {
				resultList[targetIndex].memoryList.push({
					memory: item.memory,
					total: item.total,
					partition: item.partition,
				});
			}
		});
		if (open && value) {
			const cpuActivePartitionIndex = originalCpuList.findIndex(
				(li) => li.partition === value
			);
			let cpuActivePartitionName = "";
			if (cpuActivePartitionIndex !== -1) {
				cpuActivePartitionName = originalCpuList[cpuActivePartitionIndex].name;
			}
			if (cpuActivePartitionIndex !== -1) {
				resultList.forEach((li, index) => {
					if (li.name === cpuActivePartitionName) {
						resultList[index].partition = value;
					}
				});
			}
			setActivePartition(value);
		}
		setShowCpuList(resultList);
		// eslint-disable-next-line
	}, [open, value, originalCpuList]);

	const renderType = (item: IShowCPULi) => {
		return (
			<div className={style.cpuType}>
				<img className={style.cpuIcon} src={item.picUrl} alt="" />
				<div className={style.cpuInfo}>
					<div className={style.cpuName}>{item.name}</div>
					<div className={style.cpuDetailsName}>{item.cpuName}</div>
				</div>
			</div>
		);
	};

	const renderCoreNum = (item: IShowCPULi) => {
		return item.coreNum + "核";
	};

	const renderGpuNum = (item: IQueueLi) => {
		return item.gpuNum + "卡";
	};

	const renderGpuMemory = (item: IQueueLi) => {
		return item.memory + "GB";
	};

	const setMemory = (partition: string) => {
		const copyShowCpuList: Array<IShowCPULi> = cloneDeep(showCpuList);
		const selectIndex = copyShowCpuList.findIndex((item) => {
			return item.partition === activePartition;
		});
		if (selectIndex !== -1) {
			copyShowCpuList[selectIndex].partition = partition;
		}
		// 防止被 handleRow 中的 setActiveId覆盖
		setTimeout(() => {
			setActivePartition(partition);
		}, 10);
		setShowCpuList(copyShowCpuList);
	};

	const renderMemory = (item: IShowCPULi) => {
		return (
			<MyMenu
				value={item.partition}
				options={item.memoryList.map((memoryLi) => ({
					label: `${memoryLi.memory}GB/核`,
					value: memoryLi.partition,
				}))}
				hasTriangle={true}
				setValue={setMemory}
				sx={{
					zIndex: 1601,
				}}
			>
				<span className={style.cpuMemory}>
					{
						item.memoryList.filter(
							(memoryLi) => memoryLi.partition === item.partition
						)[0].memory
					}
					GB/核
				</span>
			</MyMenu>
		);
	};

	const handleRow = (e: any) => {
		setActivePartition(e.partition);
	};

	const handleConfirm = () => {
		if (activePartition) {
			onChange && onChange(activePartition);
			setOpen(false);
		} else {
			Message.error("请先选择一个硬件队列。");
		}
	};

	const getTotal = () => {
		let total = 0;
		idInfoMap.forEach((item) => {
			if (item.partition === activePartition) {
				total = item.total;
			}
		});
		return total;
	};

	const getTitle = () => {
		let title = "";
		idInfoMap.forEach((item) => {
			if (item.partition === value) {
				title = item.title;
			}
		});
		return title;
	};

	return (
		<>
			<MyInput
				placeholder="请选择硬件队列"
				value={getTitle()}
				onClick={() => handleOpen()}
				error={error}
				helperText={helperText}
				disabled={disabled}
			></MyInput>
			{open && (
				<MyDialog
					open={open}
					title="选择硬件队列"
					onClose={() => setOpen(false)}
					onConfirm={() => handleConfirm()}
					leftSideOfButtonContent={
						<div className={style.totalBox}>
							费用（每小时）：
							<span className={style.total}>
								￥{activePartition ? getTotal() : "-"}
							</span>
						</div>
					}
					sx={{
						zIndex: 1600,
						// 让提示文案在弹窗下
						"& .MuiDialog-container": {
							"& .MuiPaper-root": {
								// 设置最大宽度， 实际宽度让子元素撑大
								maxWidth: "1920px",
								borderRadius: "8px",
							},
						},
					}}
				>
					<div className={style.queueSelectContentBox}>
						<RadioGroupOfButtonStyle
							value={queueType}
							radioOptions={queueTypes}
							handleRadio={(e: string) => setQueueType(e)}
							RadiosBoxStyle={{ width: "140px" }}
						></RadioGroupOfButtonStyle>

						<div className={style.table}>
							{queueType === "CPU" && (
								<MyTable
									rows={showCpuList.map((item) => ({
										...item,
										type: renderType(item),
										coreNumRender: renderCoreNum(item),
										memoryRender: renderMemory(item),
									}))}
									headCells={cpuHeadCells}
									fixedHead={true}
									handleRow={(e: any) => handleRow(e)}
									activeId={activePartition}
									tableKey="partition"
									loading={cpuLoading}
									disableFn={(row: any) => !row.enabled}
								></MyTable>
							)}
							{queueType === "GPU" && (
								<MyTable
									rows={originalGpuList.map((item: any) => ({
										...item,
										type: renderType(item),
										gpuNumRender: renderGpuNum(item),
										coreNumRender: renderCoreNum(item),
										gpuMemoryRender: renderGpuMemory(item),
									}))}
									headCells={gpuHeadCells}
									fixedHead={true}
									handleRow={(e: any) => handleRow(e)}
									activeId={activePartition}
									tableKey="partition"
									loading={gpuLoading}
									disableFn={(row: any) => !row.enabled}
								></MyTable>
							)}
						</div>
					</div>
				</MyDialog>
			)}
		</>
	);
};

export default QueueSelect;
