import { useEffect, useState, useCallback } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { io, Socket } from 'socket.io-client';
import type {
  QuizContent,
  QuizState,
  ExamSocketMessage,
  ExamSocketRoomMessage,
  Answer,
  CumulativeResult
} from '../types.ts';
import { useAuth } from '@/client/mobile/hooks/AuthProvider.js';

interface FullExamSocketMessage extends Omit<ExamSocketMessage, 'timestamp'> {
  id: string;
  from: string;
  timestamp: string;
}


// 工具函数：统一错误处理
const handleAsyncOperation = async <T>(
  operation: () => Promise<T>,
  errorMessage: string
): Promise<T> => {
  try {
    return await operation();
  } catch (error) {
    console.error(`${errorMessage}:`, error);
    throw error;
  }
};

// 计算收益的辅助函数
interface ProfitResult {
  profitAmount: number;  // 金额收益
  profitPercent: number; // 百分比收益
}

function calculateProfit(currentPrice: number, previousPrice: number, holdingStock: string): ProfitResult {
  if (holdingStock === '1') {
    const profitAmount = currentPrice - previousPrice;
    const profitPercent = ((currentPrice - previousPrice) / previousPrice) * 100;
    return { profitAmount, profitPercent };
  }
  return { profitAmount: 0, profitPercent: 0 };
}

// 提前声明函数
function getAnswers(client: Socket | null, roomId: string, questionId: string): Promise<Answer[]> {
  if (!client) return Promise.resolve([]);

  return new Promise((resolve) => {
    client.emit('exam:getAnswers', { roomId, questionId }, (answers: Answer[]) => {
      resolve(answers || []);
    });
  });
}

export function useSocketClient(roomId: string | null) {
  const { token } = useAuth();
  const [socket, setSocket] = useState<Socket | null>(null);
  const [isConnected, setIsConnected] = useState(false);

  // 初始化socket连接
  const { data: client } = useQuery({
    queryKey: ['socket-client', token],
    queryFn: async () => {
      if (!token) return null;

      const newSocket = io('/', {
        path: '/socket.io',
        transports: ['websocket'],
        withCredentials: true,
        query: {
          socket_token: token
        },
        reconnection: true,
        reconnectionAttempts: 5,
        reconnectionDelay: 1000,
      });

      newSocket.on('connect', () => {
        console.log('Socket connected');
      setIsConnected(true);
      });

      newSocket.on('disconnect', () => {
        console.log('Socket disconnected');
        setIsConnected(false);
      });

      newSocket.on('error', (error) => {
        console.error('Socket error:', error);
      });

      setSocket(newSocket);
      return newSocket;
    },
    enabled: !!token && !!roomId,
    staleTime: Infinity,
    gcTime: 0,
    retry: 3,
  });

  // 加入房间
  const joinRoom = useCallback(async (roomId: string) => {
    if (client) {
      client.emit('exam:join', { roomId });
    }
  }, [client]);

  // 离开房间
  const leaveRoom = useCallback(async (roomId: string) => {
    if (client) {
      client.emit('exam:leave', { roomId });
    }
  }, [client]);

  // // 发送房间消息
  // const sendRoomMessage = useCallback(async (roomId: string, message: ExamSocketMessage) => {
  //   if (client) {
  //     client.emit('exam:message', { roomId, message });
  //   }
  // }, [client]);

  // // 监听房间消息
  // const onRoomMessage = useCallback((callback: (data: ExamSocketRoomMessage) => void) => {
  //   if (client) {
  //     client.on('exam:message', (data) => {
  //       setLastMessage(data);
  //       callback(data);
  //     });
  //   }
  // }, [client]);

  // 存储答案
  const storeAnswer = useCallback(async (roomId: string, questionId: string, userId: number, answer: QuizContent, callback?: (success: Answer[]) => void) => {
    if (!client) return;

    return handleAsyncOperation(async () => {
      // // 获取历史价格数据
      // const pricesData = await new Promise<any>((resolve) => {
      //   client.emit('exam:getPrices', { roomId }, resolve);
      // });

      // if (!pricesData) {
      //   // 存储初始答案
      //   const initialAnswer: Answer = {
      //     ...answer,
      //     userId,
      //     holdingStock: '0',
      //     holdingCash: '0',
      //     profitAmount: 0,
      //     profitPercent: 0,
      //     totalProfitAmount: 0,
      //     totalProfitPercent: 0
      //   };
        
      //   client.emit('exam:storeAnswer', {
      //     roomId,
      //     questionId,
      //     userId,
      //     answer: initialAnswer
      //   }, (success: boolean) => {
      //     callback?.([initialAnswer]);
      //   });
      //   return;
      // }

      // 获取该用户的所有历史答案
      // const dates = Object.keys(pricesData).sort();
      const allUserAnswers = await getUserAnswers(roomId, userId);
      const userAnswers = allUserAnswers
        .filter((a: Answer) => a.date !== answer.date)
        // .filter((a: Answer) => dates.includes(a.date || ''))
        .map((a: Answer) => ({
          ...a,
          // price: pricesData[a.date || '']?.price || '0'
        }))
        .sort((a: Answer, b: Answer) => new Date(a.date || '').getTime() - new Date(b.date || '').getTime());

      let totalProfitAmount = 0;
      let totalProfitPercent = 0;
      
      if (userAnswers.length > 0) {
        const prevAnswer = userAnswers[userAnswers.length - 1];
        const { profitAmount, profitPercent } = calculateProfit(
          parseFloat(String(answer.price)),
          parseFloat(String(prevAnswer.price)),
          prevAnswer.holdingStock as string
        );
        
        totalProfitAmount = (prevAnswer.totalProfitAmount || 0) + profitAmount;
        totalProfitPercent = (prevAnswer.totalProfitPercent || 0) + profitPercent;
      }

      // 存储带有收益信息的答案
      const answerWithProfit: Answer = {
        ...answer,
        userId,
        profitAmount: userAnswers.length > 0 ? totalProfitAmount - (userAnswers[userAnswers.length - 1].totalProfitAmount || 0) : 0,
        profitPercent: userAnswers.length > 0 ? totalProfitPercent - (userAnswers[userAnswers.length - 1].totalProfitPercent || 0) : 0,
        totalProfitAmount,
        totalProfitPercent
      };

      client.emit('exam:storeAnswer', {
        roomId,
        questionId,
        userId,
        answer: answerWithProfit
      }, (success: boolean) => {
        callback?.([...userAnswers, answerWithProfit]);
      });
    }, '存储答案失败');
  }, [client]);

  // 清理房间数据
  const cleanupRoom = useCallback(async (roomId: string, questionId?: string) => {
    if (!client) return;

    await handleAsyncOperation(async () => {
      if (questionId) {
        client.emit('exam:cleanup', { roomId, questionId });
      } else {
        client.emit('exam:cleanup', { roomId });
      }
    }, '清理房间数据失败');
  }, [client]);

  // // 发送下一题
  // const sendNextQuestion = useCallback(async (roomId: string, state: QuizState) => {
  //   if (!client) return;

  //   return handleAsyncOperation(async () => {
  //     const message: FullExamSocketMessage = {
  //       id: `question-${Date.now()}`,
  //       type: 'question',
  //       from: 'system',
  //       timestamp: Date.now().toString(),
  //       content: {
  //         date: state.date,
  //         price: state.price,
  //         holdingStock: '0',
  //         holdingCash: '0',
  //         userId: 'system'
  //       }
  //     };

  //     // 存储当前问题状态
  //     await storeAnswer(roomId, 'current_state', 'system', {
  //       date: state.date,
  //       price: state.price,
  //       holdingStock: '0',
  //       holdingCash: '0',
  //       userId: 'system'
  //     });

  //     // 存储价格历史记录
  //     client.emit('exam:storePrice', { 
  //       roomId, 
  //       date: state.date, 
  //       price: state.price 
  //     });

  //     await sendRoomMessage(roomId, message);
  //   }, '发送题目失败');
  // }, [client, sendRoomMessage, storeAnswer]);


  // 获取历史价格
  const getPriceHistory = useCallback(async (roomId: string, date: string): Promise<string> => {
    if (!client) return '0';

    return handleAsyncOperation(async () => {
      return new Promise((resolve) => {
        client.emit('exam:getPrice', { roomId, date }, (price: string) => {
          resolve(price || '0');
        });
      });
    }, '获取历史价格失败');
  }, [client]);

  // 获取答案 (封装为useCallback)
  const getAnswersCallback = useCallback((roomId: string, questionId: string): Promise<Answer[]> => {
    if (!client) return Promise.resolve([]);
    return handleAsyncOperation(async () => {
      return getAnswers(client, roomId, questionId);
    }, '获取答案失败');
  }, [client]);

  // 清理socket连接
  useEffect(() => {
    return () => {
      if (socket) {
        socket.disconnect();
      }
    };
  }, [socket]);

  // 导出所有功能作为单个对象
  const socketRoom = {
    client,
    joinRoom,
    leaveRoom,
    // sendRoomMessage,
    // onRoomMessage
  };

  // 获取用户答案
  const getUserAnswers = useCallback(async (roomId: string, userId: number): Promise<Answer[]> => {
    if (!client || !roomId || !userId) return Promise.resolve([]);

    return handleAsyncOperation(async () => {
      return new Promise((resolve) => {
        client.emit('exam:getUserAnswers', { roomId, userId }, (answers: Answer[]) => {
          resolve(answers || []);
        });
      });
    }, '获取用户答案失败');
  }, [client]);

  const getCurrentQuestion = useCallback(async (roomId: string): Promise<QuizState | null> => {
      if (!client) return Promise.resolve(null);
      
      return handleAsyncOperation(async () => {
        return new Promise((resolve, reject) => {
          client.emit('exam:currentQuestion', { roomId }, (question: QuizState) => {
            if (!question) {
              resolve(null);
              return;
            }
            resolve(question);
          });
        });
      }, '获取当前问题失败');
  }, [client])

  const sendSettleExam = async (roomId: string) => {
      if (!client) return;
      return handleAsyncOperation(async () => {
        client.emit('exam:settle', { roomId });
      }, '发送结算消息失败');
    }

  const answerManagement = {
    storeAnswer,
    getAnswers: getAnswersCallback,
    cleanupRoom,
    // sendNextQuestion,
    getPriceHistory,
    getUserAnswers,
    getCurrentQuestion,
    sendSettleExam,
  };

  // 计算累计结果
  // const calculateCumulativeResults = useCallback((answers: Answer[]): CumulativeResult[] => {
  //   const userResults = new Map<string, CumulativeResult>();
    
  //   answers.forEach((answer) => {
  //     const userId = answer.userId;
  //     if (!userResults.has(userId)) {
  //       userResults.set(userId, {
  //         userId,
  //         totalProfitAmount: answer.totalProfitAmount || 0,
  //         totalProfitPercent: answer.totalProfitPercent || 0
  //       });
  //     }
  //   });

  //   return Array.from(userResults.values());
  // }, []);

  return {
    socketRoom,
    answerManagement,
    // calculateCumulativeResults,
    // currentQuestion,
    // setCurrentQuestion,
    // lastMessage,
    ...socketRoom,
    ...answerManagement,
    isConnected,
  };
}