import { useState, useEffect, useCallback } from 'react';
import { useWebSocket, useWebSocketSubscription } from '../actions/websocket.jsx';

/**
 * 标靶数据管理 Hook
 *
 * 功能：
 * - 通过WebSocket获取标靶数据
 * - 提供标靶的增删改查功能
 * - 自动处理WebSocket通信
 *
 * 使用方法：
 * ```jsx
 * const {
 *   targets,
 *   loading,
 *   addTarget,
 *   updateTarget,
 *   deleteTarget,
 *   refreshTargets
 * } = useTargetStorage();
 * ```
 */
export const useTargetStorage = () => {
   const [targets, setTargets] = useState([]);
   const [loading, setLoading] = useState(true);
   const [error, setError] = useState(null);
   const [isProcessing, setIsProcessing] = useState(false);

   const { isConnected, sendMessage } = useWebSocket();

   // 监听标靶数据响应
   const { latest: targetDataResponse } = useWebSocketSubscription('dev', 'getPoints');

   // 发送获取标靶数据的命令
   const fetchTargets = useCallback(() => {
      if (!isConnected) {
         console.warn('WebSocket未连接，无法获取标靶数据');
         return;
      }

      setLoading(true);
      setError(null);

      const success = sendMessage(JSON.stringify({
         "_from": "setup",
         "cmd": "getPoints",
         "values": {}
      }));

      if (!success) {
         setError('发送获取标靶数据命令失败');
         setLoading(false);
      }
   }, [isConnected, sendMessage]);

   // 处理接收到的标靶数据
   useEffect(() => {
      if (targetDataResponse && targetDataResponse.values) {
         try {
            const responseValues = targetDataResponse.values;
            // console.log('收到标靶数据:', responseValues);

            // 检查是否为空对象
            if (!responseValues || Object.keys(responseValues).length === 0) {
               console.log('服务端返回空的标靶数据');
               setTargets([]);
               setError(null);
               setLoading(false);
               return;
            }

            // 处理服务端返回的 targets 对象格式
            const targetsData = responseValues.targets || {};

            // 将对象转换为数组格式，并转换为前端需要的格式
            const formattedTargets = Object.keys(targetsData).map((targetKey) => {
               const targetInfo = targetsData[targetKey];
               const info = targetInfo.info || {};
               const rectangleArea = info.rectangle_area || {};
               const threshold = info.threshold || {};

               return {
                  key: info.id,
                  id: info.id,
                  name: info.desc || `目标${targetKey}`,
                  radius: info.radius || 40.0,
                  isReferencePoint: info.base || false,
                  // 根据实际数据结构映射阈值
                  gradientThreshold: threshold.gradient , // 梯度阈值
                  anchorThreshold: threshold.anchor,     // 锚点阈值
                  gaussianBlurThreshold: threshold.gauss || 3,
                  binaryThreshold: threshold.binary || 120,    // 保留二值化阈值
                  hasAdvancedConfig: true, // 有配置数据的都认为是有高级配置
                  // 保留原始服务端数据
                  rectangleArea: rectangleArea,
                  perspective: targetInfo.perspective || null,
                  handlerInfo: targetInfo.handler_info || null,
               };
            }).sort((a, b) => Number(a.id) - Number(b.id)); // 按id数字升序排序;

            setTargets(formattedTargets);
            setError(null);
            // console.log('解析到标靶数据:', formattedTargets);
         } catch (err) {
            console.error('处理标靶数据失败:', err);
            setError('处理标靶数据失败');
            setTargets([]); // 出错时设置为空数组
         } finally {
            setLoading(false);
         }
      } else if (targetDataResponse && !targetDataResponse.values) {
         // 如果收到响应但没有values，可能是空响应
         console.log('收到空的标靶数据响应');
         setTargets([]);
         setError(null);
         setLoading(false);
      }
   }, [targetDataResponse]);

   // WebSocket连接建立后自动获取数据
   useEffect(() => {
      if (isConnected) {
         fetchTargets();
      }
   }, [isConnected, fetchTargets]);

   // 通用的标靶数据处理纯函数
   const buildTargetsPayload = useCallback((targetsArray) => {
      const targets = {};

      targetsArray.forEach((target) => {
         // 使用标靶的原始ID作为键，而不是数组索引
         const targetKey = target.id || target.key || Date.now().toString();
         const rectangleArea = target.rectangleArea || {};

         targets[targetKey] = {
            info: {
               rectangle_area: {
                  x: rectangleArea.x || 0,
                  y: rectangleArea.y || 0,
                  w: rectangleArea.w || rectangleArea.width || 100,
                  h: rectangleArea.h || rectangleArea.height || 100,
               },
               threshold: {
                  binary: target.binaryThreshold || 120,
                  gauss: target.gaussianBlurThreshold || 1,
                  gradient: target.gradientThreshold,
                  anchor: target.anchorThreshold,
               },
               radius: parseFloat(target.radius) || 40.0,
               id: target.id || target.key,
               desc: target.name || `target_${targetKey}`,
               base: target.isReferencePoint || false,
            },
            perspective: target.perspective || [
               [1.0, 0, 0],
               [0, 1.0, 0],
               [0, 0, 1.0],
            ],
         };
      });

      return {
         _from: "setup",
         cmd: "setPoints",
         values: {
            targets: targets,
         },
      };
   }, []);

   // 通用的发送标靶数据函数
   const sendTargetsData = useCallback((outputData, operationType, targetIdentifier) => {
      if (isProcessing) {
         console.log(`${operationType}请求正在处理中，忽略重复请求`);
         return false;
      }

      setIsProcessing(true);
      console.log(`准备发送的${operationType}数据:`, outputData);

      try {
         // 发送更新后的标靶列表到服务端
         const jsonString = JSON.stringify(outputData, null, 2).replace(
            /"perspective":\s*\[\s*\[\s*1,\s*0,\s*0\s*\],\s*\[\s*0,\s*1,\s*0\s*\],\s*\[\s*0,\s*0,\s*1\s*\]\s*\]/g,
            '"perspective": [\n               [1.0, 0, 0],\n               [0, 1.0, 0],\n               [0, 0, 1.0]\n            ]'
         );

         const success = sendMessage(jsonString);

         if (success) {
            console.log(`${operationType}标靶成功，已发送更新数据到服务端:`, targetIdentifier);
            console.log('发送的数据:', outputData);
            // 延迟重新获取数据，确保服务器处理完成
            setTimeout(() => {
               console.log('开始重新获取标靶数据...');
               fetchTargets();
               setIsProcessing(false);
            }, 1000);
            return true;
         } else {
            console.error(`发送${operationType}数据到服务端失败`);
            setIsProcessing(false);
            return false;
         }
      } catch (error) {
         console.error(`${operationType}数据处理失败:`, error);
         setIsProcessing(false);
         return false;
      }
   }, [sendMessage, fetchTargets, isProcessing]);

   // 添加标靶
   const addTarget = useCallback((targetInfo) => {
      if (!isConnected) {
         console.warn('WebSocket未连接，无法添加标靶');
         return false;
      }

      try {
         const success = sendMessage(JSON.stringify({
            "_from": "setup",
            "cmd": "addPoint",
            "values": targetInfo
         }));

         if (success) {
            // 本地更新（实际数据会通过WebSocket响应更新）
            const newTarget = {
               ...targetInfo,
               key: targetInfo.id || Date.now().toString(),
               id: targetInfo.id || Date.now().toString(),
            };
            setTargets(prev => [...prev, newTarget]);
            console.log('发送添加标靶命令成功');
            return true;
         }

         return false;
      } catch (error) {
         console.error('添加标靶失败:', error);
         return false;
      }
   }, [isConnected, sendMessage]);

   // 更新标靶
   const updateTarget = useCallback((targetInfo) => {
      console.log('准备更新标靶:', targetInfo);

      if (!isConnected) {
         console.warn('WebSocket未连接，无法更新标靶');
         return false;
      }

      try {
         // 先计算更新后的数据，不依赖状态更新
         setTargets(prev => {
            console.log('更新标靶前的状态:', prev);
            const updatedTargets = prev.map(target =>
               target.key === targetInfo.key || target.id === targetInfo.id
                  ? { ...target, ...targetInfo }
                  : target
            );
            console.log('更新标靶后的状态:', updatedTargets);
            console.log('更新的标靶匹配:', prev.map(t => ({
               id: t.id,
               key: t.key,
               match: t.key === targetInfo.key || t.id === targetInfo.id,
               isUpdated: t.key === targetInfo.key || t.id === targetInfo.id ? '是' : '否'
            })));

            // 立即构建并发送数据，使用计算出的 updatedTargets
            console.log('准备构建payload，使用的数据:', updatedTargets);
            const outputData = buildTargetsPayload(updatedTargets);
            console.log('构建的payload:', outputData);

            // 检查payload是否为空
            if (!outputData.values.targets || Object.keys(outputData.values.targets).length === 0) {
               console.warn('警告：构建的payload为空！这会导致所有标靶被清除');
            }

            sendTargetsData(outputData, '更新', targetInfo.key || targetInfo.id);

            return updatedTargets;
         });

         return true;

      } catch (error) {
         console.error('更新标靶失败:', error);
         return false;
      }
   }, [isConnected, buildTargetsPayload, sendTargetsData]);

   // 删除标靶
   const deleteTarget = useCallback((targetKey) => {
      console.log('准备删除标靶:', targetKey);

      if (!isConnected) {
         console.warn('WebSocket未连接，无法删除标靶');
         return false;
      }

      try {
         // 先计算删除后的数据，不依赖状态更新
         setTargets(prev => {
            console.log('删除标靶前的状态:', prev);
            const updatedTargets = prev.filter(target => target.key !== targetKey && target.id !== targetKey);
            console.log('删除标靶后的状态:', updatedTargets);
            console.log('删除的标靶ID匹配:', prev.map(t => ({
               id: t.id,
               key: t.key,
               match: t.key === targetKey || t.id === targetKey
            })));

            // 立即构建并发送数据，使用计算出的 updatedTargets
            console.log('准备构建payload，使用的数据:', updatedTargets);
            const outputData = buildTargetsPayload(updatedTargets);
            console.log('构建的payload:', outputData);

            // 检查payload是否为空
            if (!outputData.values.targets || Object.keys(outputData.values.targets).length === 0) {
               console.warn('警告：构建的payload为空！这会导致所有标靶被清除');
            }

            sendTargetsData(outputData, '删除', targetKey);

            return updatedTargets;
         });

         return true;

      } catch (error) {
         console.error('删除标靶失败:', error);
         return false;
      }
   }, [isConnected, buildTargetsPayload, sendTargetsData]);

   // 根据key查找标靶
   const getTargetByKey = useCallback((key) => {
      return targets.find(target => target.key === key || target.id === key);
   }, [targets]);

   // 刷新标靶数据
   const refreshTargets = useCallback(() => {
      fetchTargets();
   }, [fetchTargets]);

   // 清空标靶数据
   const clearTargets = useCallback(() => {
      setTargets([]);
   }, []);

   return {
      targets,
      loading,
      error,
      isProcessing,
      addTarget,
      updateTarget,
      deleteTarget,
      getTargetByKey,
      refreshTargets,
      clearTargets,
      // WebSocket连接状态
      isConnected,
   };
};

export default useTargetStorage;
