import React, { useState, useEffect, useRef, useCallback, useMemo } from "react";
import { Button, Checkbox, CheckboxProps, Drawer, Input, InputNumber, message, Select, Spin, Switch } from "antd";
import { DownOutlined, UpOutlined, LeftOutlined, RightOutlined, UndoOutlined, RedoOutlined } from '@ant-design/icons';
import { useNavigate } from "react-router";
import {
	fetchAnalysisReport,
	getAlignPointsByRailSize,
	startMeasurement,
	stopMeasurement,
} from "../../../services/measure/analysis";
import { getBaseRecordPointSetByCode, gx_list } from "../../../services/track/trackShape"
import { createWebSocket, sharedWsUrl } from "../../../services/socket";
import { switchMeasureAfterSave } from "../../../store/features/contextSlice";
import measureState, { updateGxState, updateMeasureData } from "../../../store/measure/measureState";
import { AnalysisReport, trackItem } from "../../../services/measure/type";
import { MeasureState, TaskState, TrackRecordSig } from "../../../services/wsTypes";
import { useAppDispatch, useAppSelector } from "../../../utils/hooks";
import Gr_round from "../../../assets/green_round.svg";
import Bl_round from "../../../assets/blue_round.svg";
import icon_left from "../../../assets/icon_left.svg";
import icon_right from "../../../assets/icon_right.svg";
import icon_up from "../../../assets/icon_up.svg";
import icon_down from "../../../assets/icon_down.svg";
import icon_leftR from "../../../assets/icon_leftR.svg";
import icon_rightR from "../../../assets/icon_rightR.svg";
import MeasurementCanvas, { AnalysisData, BenchmarkShape, MeasurementCanvasRef, Point } from "./konva/MeasurementCanvas";
import "./MeasureAction.scss";
import { GX_CODE } from "../../../constant";
// 创建 websocket 客户端
const wsClient = createWebSocket(sharedWsUrl);

export default function MeasureAction() {
	const dispatch = useAppDispatch();
	const navigate = useNavigate();
	const deviceInfo = useAppSelector(store => store.context.device);
	const measureState = useAppSelector((store) => store.measureState);
	const [gxCode, setGxCode] = useState<string>(GX_CODE)
	
	const STEP_COLOR_GREEN = "green";
	const STEP_COLOR_BLUE = "blue";
	const STEP_COLOR_GREY = "grey";
	/** ----------------------- 引用 ----------------------- **/
	const canvasRef = useRef<MeasurementCanvasRef>(null);
	const leftPoints = useRef<{ x: number; y: number }[]>([]);
	const rightPoints = useRef<{ x: number; y: number }[]>([]);
	const isLeftFinished = useRef(false);

	/** ----------------------- 状态 ----------------------- **/
	const [showGrid, setShowGrid] = useState(true);
	const [showStandard, setShowStandard] = useState(true);
	const [showMark, setShowMark] = useState(true);
	// showMark的备份，记录showMark最近一次的值
	const [angleMarkBackup, setAngleMarkBackup] = useState(true);
	const afterSave = useAppSelector(store => store.context.newMeasureAfterSave);
	const [startBtnText, setStartBtnText] = useState("开始测量");
	const [measurementFinished, setMeasurementFinished] = useState(false);

	// 【分析】之后，会得到分析报告
	const [analysisReport, setAnalysisReport] = useState<AnalysisReport | null>(null);

	// 初始状态列表
	const initialStatusList = useMemo(
		() => [
			{ name: "请移动到顶部，停顿2秒", background: "#ececec", isReady: false, color: STEP_COLOR_GREY },
			{ name: "开始测量左侧", background: "#ececec", isReady: false, color: STEP_COLOR_GREY },
			{ name: "左侧测量完成", background: "#ececec", isReady: false, color: STEP_COLOR_GREY },
			{ name: "请移动到顶部，停顿2秒", background: "#ececec", isReady: false, color: STEP_COLOR_GREY },
			{ name: "开始测量右侧", background: "#ececec", isReady: false, color: STEP_COLOR_GREY },
			{ name: "右侧测量完成", background: "#ececec", isReady: false, color: STEP_COLOR_GREY },
		],
		[]
	);
	const [statusList, setStatusList] = useState(initialStatusList);
	// 打开抽屉（显示分析结果）
	const [openDrawer, setOpenDrawer] = useState(false);

	/** ----------------------- 事件处理函数 ----------------------- */
	// 切换保存后自动开始新测量
	const onAfterSaveChange: CheckboxProps["onChange"] = e => {
		dispatch(switchMeasureAfterSave(e.target.checked));
	};

	useEffect(()=>{
		setGxCode(measureState.gxCode)
	}, [measureState])
	

	// 分析按钮点击事件
	const onAnalysisBtnClick = () => {
		if (analysisReport) {
			setOpenDrawer(true);
			return;
		}
		fetchAnalysisReport(gxCode).then(res => {
			if (res.success) {
				const report: AnalysisReport = res.data;
				console.log(report);
				// 更新 canvas 的分析数据
				if (report && report.angleAnalysisList) {
					// 先过滤掉 distance 为 null 的数据
					const validItems = report.angleAnalysisList.filter(item => item.distance !== null);
					const analysisData: AnalysisData[] = validItems.map(item => ({
						pointA: { x: parseFloat(item.pointA.x), y: parseFloat(item.pointA.y) },
						pointB: { x: parseFloat(item.pointB.x), y: parseFloat(item.pointB.y) },
						base: { x: parseFloat(item.pointA.x), y: parseFloat(item.pointA.y) },
						measure: { x: parseFloat(item.pointB.x), y: parseFloat(item.pointB.y) },
						distance: parseFloat(item.distance),
						describe: item.describe,
					}));
					canvasRef.current?.setAnalysisData(analysisData);
				}
				setAnalysisReport(report);
				setOpenDrawer(true);
			} else {
				message.error("分析报告请求失败: " + res.data.info);
			}
		});
	};

	// 开始/重新测量按钮点击事件
	const onStart = useCallback(() => {
		if (!deviceInfo.isConnected) {
			message.error("请先连接设备");
			return;
		}
		// if(deviceInfo.power < 20){
		// 	message.error('电量低于20%，请充电后再测量！')
		// 	return
		// }
		// 重置测量相关状态
		setMeasurementFinished(false);
		setAnalysisReport(null);
		setshowCalibration(false)//校准线
		dispatch(updateMeasureData([]))
		isLeftFinished.current = false;
		leftPoints.current = [];
		rightPoints.current = [];
		canvasRef.current?.clearShapes();
		canvasRef.current?.resetCanvas();
		startMeasurement().then(res => {
			if (res.status !== 0) {
				message.error(res.data.info);
			} else {
				let list = [...initialStatusList]
				list.forEach((item, index) => {
					if(index === 0){
						item.color = STEP_COLOR_BLUE;
					}else{
						item.color = STEP_COLOR_GREY;
					}
				})
				setStatusList(list);
				message.success("已通知设备开始测量");
				setStartBtnText("重新测量");
			}
		});
	}, [initialStatusList, startBtnText, deviceInfo]);

	//停止测量
	const onStop = () => {
		stopMeasurement().then(res=>{
			if (res.status !== 0) {
			}else{
				message.error('已停止测量')
			}
		}).catch(e=>{
			message.error('调用出错')
		})
	}

	// 保存按钮点击事件
	const onSaveBtnClick = () => {
		dispatch(updateMeasureData(newMeasureData))
		navigate('/measure/config')
		//将校准的数据存入store
	};

	//校准
	const [showCalibration, setshowCalibration] = useState(false)
	const [caloading, setCaLoading] = useState(false)
	const onCalibrationBtnClick = () => {
		setCaLoading(true)
		//获取校准数据
		getAlignPointsByRailSize({railSize:railSize}).then(res => {
			if(res.success){
				setshowCalibration(true)
				canvasRef.current?.setMeasurementCalibrationData(res.data)
			}else{
				message.error('校准失败！')	
			}
			setCaLoading(false)
		}).catch(e=>{
			setCaLoading(false)
			message.error('校准失败！')
		})
	}

	// 辅助函数：渲染状态项的图标
	const renderStatusIcon = (item: (typeof initialStatusList)[0]) => {
		if (item.color === STEP_COLOR_GREEN) {
			return <img src={Gr_round} alt="green" />;
		} else if (item.color === STEP_COLOR_BLUE) {
			return <img src={Bl_round} alt="blue" />;
		} else {
			return (
				<div
					style={{
						width: "22px",
						height: "22px",
						background: "#c0c0c0",
						borderRadius: "50%",
						marginTop: "10px",
					}}
				/>
			);
		}
	};

	/** ----------------------- WebSocket 消息处理 ----------------------- **/
	useEffect(() => {
		// 处理任务状态消息
		const handleStateMessage = (state: MeasureState["data"]) => {};
		// 处理事件消息
		const handleEventMessage = (type: TaskState["data"]) => {
			setStatusList(prev => {
				const updated = [...prev];
				switch (type) {
					case "START_RECORD_LEFT":
						updated[0].color = STEP_COLOR_GREEN;
						updated[1].color = STEP_COLOR_BLUE;
						const audio1 = new Audio("/audio/begin_left.mp3");
						// 播放音频
						audio1
							.play()
							.then(() => {
								console.log("音频开始播放");
							})
							.catch(err => {
								console.error("播放音频时出错:", err);
							});
						break;
					case "FINISH_RECORD_LEFT":
						updated[1].color = STEP_COLOR_GREEN;
						updated[2].color = STEP_COLOR_GREEN;
						updated[3].color = STEP_COLOR_BLUE;
						isLeftFinished.current = true;
						const audio2 = new Audio("/audio/end_left.mp3");
						// 播放音频
						audio2
							.play()
							.then(() => {
								console.log("音频开始播放");
							})
							.catch(err => {
								console.error("播放音频时出错:", err);
							});
						break;
					case "START_RECORD_RIGHT":
						updated[3].color = STEP_COLOR_GREEN;
						updated[4].color = STEP_COLOR_BLUE;
						const audio3 = new Audio("/audio/begin_right.mp3");
						// 播放音频
						audio3
							.play()
							.then(() => {
								console.log("音频开始播放");
							})
							.catch(err => {
								console.error("播放音频时出错:", err);
							});
						break;
					case "FINISH_RECORD_RIGHT":
						updated[4].color = STEP_COLOR_GREEN;
						updated[5].color = STEP_COLOR_GREEN;
						setMeasurementFinished(true);
						const audio4 = new Audio("/audio/end_right.mp3");
						// 播放音频
						audio4
							.play()
							.then(() => {
								console.log("音频开始播放");
							})
							.catch(err => {
								console.error("播放音频时出错:", err);
							});
						break;
					case "WRONG_SIDE":
						const audio5 = new Audio("/audio/alert_left.mp3");
						// 播放音频
						audio5
							.play()
							.then(() => {
								console.log("音频开始播放");
							})
							.catch(err => {
								console.error("播放音频时出错:", err);
							});
						// 把状态全部置灰
						updated.forEach(u => (u.color = STEP_COLOR_GREY));
						// 调用停止测量
						onStop();
						break;
					default:
						break;
				}
				return updated;
			});
		};

		// 处理点数据消息
		const handlePointReport = (pointData: TrackRecordSig["data"]) => {
			if (!isLeftFinished.current) {
				leftPoints.current.push(pointData);
				canvasRef.current?.setMeasurementDataLeft([...leftPoints.current]);
			} else {
				rightPoints.current.push(pointData);
				canvasRef.current?.setMeasurementDataRight([...rightPoints.current]);
			}
		};

		const subscription = wsClient.dataOb.subscribe(data => {
			if (data.path === "/api/measurement-task/get-task-state") {
				handleStateMessage(data.data);
			} else if (data.path === "/api/measurement-task/event") {
				handleEventMessage(data.data);
			} else if (data.path === "/api/measurement-task/point-report") {
				handlePointReport(data.data);
			}
		});
		wsClient.connect();
		return () => subscription.unsubscribe();
	}, [onStart]);

	/** ----------------------- 页面加载获取基础图形数据 -------基线---------------- **/
	useEffect(() => {
		queryBasePoints(gxCode)
		//获取轨型
		getTrackDataList()
	}, []);

	//获取测量基线
	const queryBasePoints = (gxCode:string) => {
		getBaseRecordPointSetByCode(gxCode).then(res => {
			if (res.success) {
				const benchmarkShapes = JSON.parse(res.data.points) as BenchmarkShape[];
				if (canvasRef.current) {
					console.log("解析后的基础图形数据：", benchmarkShapes);
					canvasRef.current.setBenchmarkData(benchmarkShapes);
				}
			}
		});
	}

	/********************************轨型数据************************************* */
	const [trackList, setTrackList] = useState<trackItem[]>([])
	const [defaultTrackValue, setDefaultTrackValue] = useState<string>()
	const getTrackDataList = () => {
		gx_list().then(res => {
			if(res.data && res.data.length){
				let resData:trackItem[] = res.data;
				let list:trackItem[] = []
				resData.map(item => {
					if(item.points){
						list.push(item)
					}
				})
				setTrackList(list)
			}
		})
	}

	useEffect(()=>{
		if(trackList && trackList.length){
			setDefaultTrackValue(trackList[0].code)
		}
	},[trackList])


	//当前选择的轨型 默认"GX-60"
	const [railSize, setRailSize] = useState<string>(GX_CODE)
	const onTrackChange = (value: string) => {
		setRailSize(value)
		queryBasePoints(value)
		//缓存至STORE
		dispatch(updateGxState(value))
	}

	//上下移动
	const onMoveLine = (type:string) => {
		let list = canvasRef.current?.getMeasurementCalibrationData()
		if(list && list.length){
			list.forEach(item => {
				if(type === 'up'){//向上移动，原数据减y X轴不动
					item.y = item.y - distance/1000;
				}
				if(type === 'down'){//向上移动，原数据加y X轴不动
					item.y = item.y + distance/1000;
				}
				if(type === 'left'){//向左移动，原数据减x Y轴不动
					item.x = item.x - distance/1000;
				}
				if(type === 'right'){//向右移动，原数据加x Y轴不动
					item.x = item.x + distance/1000;
				}
			})
			canvasRef.current?.setMeasurementCalibrationData(list)
			setNewMeasureData(list)
		}
	}

	//旋转
	let [measurementRotation, setMeasurementRotation] = useState<number>(0)
	let [newMeasureData, setNewMeasureData] = useState<Point[]>()
	let [angle, setAngle] = useState<number>(1);//角度单位 分
	let [distance, setDistance] = useState<number>(10)
	const onRotationLine = (type:string) => {
		let mrValue = 0
		if(type === 'left'){//逆时针
			mrValue = measurementRotation - (angle/60) * Math.PI / 180;
		}
		if(type === 'right'){//顺时针
			mrValue = measurementRotation + (angle/60) * Math.PI / 180;
		}
		let list = canvasRef.current?.getMeasurementCalibrationData()
		if(list && list.length){
			list.forEach((item, index) => {
				let cloneItem = rotatePoint(item, mrValue)
				item.x = cloneItem.x
				item.y = cloneItem.y
			})
			canvasRef.current?.setMeasurementCalibrationData(list)
			setNewMeasureData(list)
		}
	}

	const rotatePoint = (pt:{x:number;y:number}, angle:number) => {
		const item = {
			x: pt.x * Math.cos(angle) - pt.y * Math.sin(angle),
			y: pt.x * Math.sin(angle) + pt.y * Math.cos(angle)
		};
		return item
	}

	/** ----------------------- 渲染 ----------------------- **/
	return (
		<>
			<div className="flex h-full px-6">
				{/* 左侧区域：包含开关区域和测量画布 */}
				<div className="">
					
					<div className="relative flex gap-4 items-center py-3">
						<Select
								className="w-[150px]"
                placeholder="请选择轨型"
								key={defaultTrackValue}
								defaultValue={defaultTrackValue}
								onChange={onTrackChange}
                options={trackList.map((item) => ({
                  label: item.name,
                  value: item.code,
                }))}
              ></Select>
						{/* <div
							className="absolute text-primary border border-primary rounded px-4 py-[2px] font-medium cursor-pointer hover:text-primary/[0.8]"
							onClick={() => navigate("../config", { replace: true })}>
							返回
						</div> */}
						<section className="ml-auto flex gap-4 items-center">
							{/* 参考线开关 */}
							<div className="flex gap-2 items-center">
								<Switch defaultChecked onChange={checked => setShowGrid(checked)} />
								<span>参考线</span>
							</div>
							{/* 标准线开关 */}
							<div className="flex gap-2 items-center">
								<Switch
									checked={showStandard}
									onChange={checked => {
										setShowStandard(checked);
										if (!checked) {
											setAngleMarkBackup(showMark);
											setShowMark(false);
										} else {
											setShowMark(angleMarkBackup);
										}
									}}
								/>
								<span>标准线</span>
							</div>
							{/* 角度线开关，仅在点击分析按钮后显示 */}
							{analysisReport && (
								<div className="flex gap-2 items-center">
									<Switch
										checked={showMark}
										disabled={!showStandard}
										onChange={checked => {
											setShowMark(checked);
											setAngleMarkBackup(checked);
										}}
									/>
									<span>角度线</span>
								</div>
							)}
						</section>
					</div>
					<Spin spinning={caloading} tip="正在校准...">
						<div className="relative">
							<MeasurementCanvas
								width={800}
								height={600}
								logicalExtent={{ minX: -50, maxX: 50, minY: -20, maxY: 60 }}
								gridStep={1}
								origin={{ x: 0, y: 20 }}
								pixelPerMm={8}
								maxZoom={10}
								showGrid={showGrid}
								showBenchmark={showStandard}
								showAnalysis={showMark}
								showScale={false}
								scaleInterval={1}
								showCoordinates={showGrid}
								showCalibration={showCalibration}
								ref={canvasRef}
							/>
						</div>
						{showCalibration && 
							<div className="flex justify-center h-[50px]">
								<div className="mt-[12px]">
									移动距离：<InputNumber defaultValue={distance} placeholder="微米" onChange={(value) => value !== null && setDistance(Number(value))}></InputNumber>
									<span>微米</span>
								</div>
								<img width={40} src={icon_left} onClick={()=>(onMoveLine("left"))} className="text-[20px] ml-[20px]" alt="左移"/>
								<img width={40} src={icon_right} onClick={()=>(onMoveLine("right"))} className="text-[20px] ml-[20px]" alt="右移"/>
								<img width={40} src={icon_up} onClick={()=>(onMoveLine("up"))} className="text-[20px] ml-[20px]" alt="上移"/>
								<img width={40} src={icon_down} onClick={()=>(onMoveLine("down"))} className="text-[20px] ml-[20px]" alt="下移"/>
								<img width={40} src={icon_leftR} onClick={()=>(onRotationLine("left"))} className="text-[20px] ml-[20px]" alt="逆时针旋转"/>
								<img width={40} src={icon_rightR} onClick={()=>(onRotationLine("right"))} className="text-[20px] ml-[20px]" alt="顺时针旋转"/>
								<div className="mt-[12px] ml-[20px]">
									旋转角度：<InputNumber placeholder="请输入角度" defaultValue={angle}  onChange={(value) => value !== null && setAngle(Number(value))}></InputNumber>
									<span>分</span>
								</div>
							</div>
						}
					</Spin>
				</div>
				{/* 右侧区域：根据 showAnalysisTable 状态显示测量步骤或分析表格 */}
				<div className="min-w-[300px] flex-auto py-6 flex flex-col items-center">
					<div>
						<h1 className="font-medium text-xl text-center">测量步骤</h1>
						<div className="w-[13rem] mt-5">
							{statusList.map((item, index) => (
								<div
									key={index}
									style={{ background: item.background, borderRadius: "20px" }}
									className="mt-[10px] h-[40px]">
									<div style={{ display: "flex", lineHeight: "40px" }} className="pl-[1rem]">
										{renderStatusIcon(item)}
										<div className="pl-[5px]">{item.name}</div>
									</div>
								</div>
							))}
						</div>
						<section className="flex flex-col items-center gap-4 mt-6 border-t border-[#D8D8D8] py-4">
							<Button style={{ width: 200 }} size="large" type="primary" onClick={onStart}>
								{startBtnText}
							</Button>
							<Button
								style={{ width: 200 }}
								size="large"
								type="primary"
								onClick={onAnalysisBtnClick}
								disabled={!measurementFinished}>
								分析
							</Button>
							<Button
								style={{ width: 200 }}
								size="large"
								type="primary"
								onClick={onSaveBtnClick}
								disabled={!measurementFinished}
								>
								保存
							</Button>
							<Button
								style={{ width: 200 }}
								size="large"
								type="primary"
								onClick={onCalibrationBtnClick}
								disabled={!measurementFinished}
								>
								校准
							</Button>
							<Checkbox checked={afterSave} onChange={onAfterSaveChange}>
								保存后自动开始新测量
							</Checkbox>
						</section>
					</div>
				</div>
			</div>

			<Drawer title="分析结果" onClose={() => setOpenDrawer(false)} open={openDrawer}>
				{analysisReport && (
					<>
						<div className="analysis-table">
							<table
								style={{
									width: "100%",
									borderCollapse: "collapse",
									border: "1px solid #ccc",
									textAlign: "center",
								}}>
								<tbody>
									<tr style={{ height: "40px", fontSize: "18px", color: "#9E9E9E" }}>
										<td style={{ padding: "8px", border: "1px solid #ccc" }}>W1垂直磨耗</td>
										<td style={{ padding: "8px", border: "1px solid #ccc" }}>{analysisReport.w1}</td>
									</tr>
									<tr style={{ height: "40px", fontSize: "18px", color: "#9E9E9E" }}>
										<td style={{ padding: "8px", border: "1px solid #ccc" }}>轨头宽度</td>
										<td style={{ padding: "8px", border: "1px solid #ccc" }}>
											{analysisReport.railHeadWidth}
										</td>
									</tr>
									{analysisReport.angleAnalysisList.map((item, index) => (
										<tr key={index} style={{ height: "40px", fontSize: "18px", color: "#9E9E9E" }}>
											<td style={{ padding: "8px", border: "1px solid #ccc" }}>{item.describe}</td>
											<td style={{ padding: "8px", border: "1px solid #ccc" }}>{item.distance}</td>
										</tr>
									))}
								</tbody>
							</table>
						</div>
						{/* <div className="mt-5 flex justify-center">
							<Button style={{ minWidth: 200 }} size="large" type="primary" onClick={onExport}>
								导出
							</Button>
						</div> */}
					</>
				)}
			</Drawer>
		</>
	);
}
