import { create } from 'zustand';
import LotteryService from '../services/lotteryService';
import ApiService from '../services/apiService';
import AuthService from '../services/authService';
import type { PrizeConfig, SystemConfig } from '../database/database';
import EventService, { EVENT_TYPES, type PrizesUpdatedEventData } from '../services/eventService';

// 定义概率信息接口
interface ProbabilityInfo {
  prize: Prize;
  dynamicProbability: number;
  remainingRatio: number;
  adjustedForDrawLimit?: boolean;
}

// 奖项配置接口
export interface Prize {
  id: string;
  name: string;
  level: number;
  totalQuantity: number;
  remainingQuantity: number;
  probability: number;
  is_active: boolean;
}

// 抽奖结果接口
export interface DrawResult {
  success: boolean;
  prize?: {
    id: string;
    name: string;
    level: number;
    prize_name?: string; // 兼容数据库字段
  };
  message: string;
  remaining?: number;
  studentId?: string;
  timestamp?: number;
  formattedStudentId?: string;
}

// 应用状态接口
export interface AppState {
  // 用户认证
  isAuthenticated: boolean;
  
  // 奖项配置
  prizes: Prize[];
  
  // 抽奖相关
  currentStudentId: string;
  drawResult: DrawResult | null;
  isDrawing: boolean;
  drawMessage: string;
  
  // 系统配置
  maxDrawTimes: number;
  hidePositions: number[];
  systemConfig: SystemConfig | null;
  
  // 操作方法
  login: (password: string) => Promise<boolean>;
  logout: () => void;
  setStudentId: (id: string) => void;
  startDraw: (studentId: string) => Promise<DrawResult>;
  resetDraw: () => void;
  loadPrizes: () => Promise<void>;
  initializeApp: () => Promise<void>;
  loadSystemConfig: () => Promise<void>;
  setSystemConfig: (config: SystemConfig | null) => void;
  calculateDynamicProbabilities: (prizeList: Prize[]) => ProbabilityInfo[];
  checkAuthStatus: () => void;
  autoRefreshAuth: () => void;
  getTokenRemainingTime: () => number;
  cleanup: () => void;
}

// 转换数据库奖项到应用奖项格式
const convertPrizeConfig = (dbPrize: PrizeConfig): Prize => ({
  id: dbPrize.id,
  name: dbPrize.prize_name,
  level: dbPrize.prize_level,
  totalQuantity: dbPrize.total_quantity,
  remainingQuantity: dbPrize.remaining_quantity,
  probability: dbPrize.probability,
  is_active: dbPrize.is_active
});

export const useAppStore = create<AppState>()(
  (set, get) => {
    const lotteryService = LotteryService.getInstance();
    const authService = AuthService.getInstance();
    
    // 初始化事件监听
    const eventService = EventService.getInstance();
    
    // 监听奖品更新事件，实现智能无感刷新
    eventService.subscribe(EVENT_TYPES.PRIZES_UPDATED, ((event: CustomEvent<PrizesUpdatedEventData>) => {
      const { updatedPrizes } = event.detail;
      const currentPrizes = get().prizes;
      
      // 将数据库格式转换为应用格式
      const convertedPrizes = (updatedPrizes as unknown as PrizeConfig[]).map(convertPrizeConfig);
      
      // 智能比较：检查是否有任何字段发生变化
      const hasChanges = JSON.stringify(convertedPrizes) !== JSON.stringify(currentPrizes);
      
      // 只有在数据真正变化时才更新状态，避免不必要的重新渲染
      if (hasChanges) {
        console.log('检测到奖品数据变化，更新状态');
        set({ prizes: convertedPrizes });
      }
    }) as EventListener);
    
    return {
      // 初始状态 - 从AuthService检查登录状态
      isAuthenticated: authService.isAuthenticated(),
      prizes: [],
      currentStudentId: '',
      drawResult: null,
      isDrawing: false,
      drawMessage: '',
      maxDrawTimes: 1,
      hidePositions: [3, 4, 5, 6],
      systemConfig: null,
      
      // 初始化应用
      initializeApp: async () => {
        try {
          // 检查登录状态
          get().checkAuthStatus();
          
          // 设置token过期回调
          authService.setTokenExpiredCallback(() => {
            console.log('Token过期，自动登出');
            set({ isAuthenticated: false });
          });
          
          // 启动token监控
          authService.startTokenMonitoring();
          
          // 加载系统配置
          await get().loadSystemConfig();
          
          await get().loadPrizes();
          const hidePositions = await lotteryService.getHidePositions();
          set({ hidePositions });
          
          // 设置自动刷新token的定时器
          setInterval(() => {
            get().autoRefreshAuth();
          }, 5 * 60 * 1000); // 每5分钟检查一次
        } catch (error) {
          console.error('Initialize app failed:', error);
        }
      },
      
      // 登录
      login: async (inputPassword: string) => {
        try {
          const result = await authService.login(inputPassword);
          if (result.success) {
            set({ isAuthenticated: true });
            console.log('登录成功，状态已更新');
            return true;
          }
          return false;
        } catch (error) {
          console.error('登录失败:', error);
          return false;
        }
      },
      
      // 登出方法
      logout: () => {
        authService.logout();
        set({ 
          isAuthenticated: false,
          drawResult: null,
          drawMessage: ''
        });
        console.log('已登出');
      },
      
      // 设置学号
      setStudentId: (id: string) => {
        set({ currentStudentId: id, drawMessage: '' });
      },
      
      // 加载奖项配置
      loadPrizes: async () => {
        try {
          console.log('Store loadPrizes - 开始加载奖项数据');
          console.log('Store loadPrizes - 当前URL:', window.location.href);
          
          const apiService = ApiService.getInstance();
          const dbPrizes = await apiService.getAllPrizes();
          console.log('Store loadPrizes - 从数据库获取的原始奖项:', dbPrizes);
          
          const prizes = (dbPrizes || []).map(convertPrizeConfig);
          console.log('Store loadPrizes - 处理后的奖项数据:', prizes);
          
          set({ prizes });
          
          console.log('Store loadPrizes - 奖项数据已更新到状态');
          
          // 注意：不在这里触发PRIZES_UPDATED事件，避免与WebSocket事件形成循环
          // WebSocket事件应该是数据变化的唯一触发源
        } catch (error) {
          console.error('Store loadPrizes - 加载奖项失败:', error);
          console.error('Store loadPrizes - 错误详情:', error.stack);
          
          // 提供更详细的错误信息
          if (error instanceof TypeError && error.message.includes('fetch')) {
            console.error('Store loadPrizes - 网络连接错误，请检查后端服务是否正常运行');
          } else if (error.message?.includes('Failed to fetch')) {
            console.error('Store loadPrizes - API请求失败，可能是网络问题或服务器未响应');
          }
          
          // 设置空数组避免组件渲染错误
          set({ prizes: [] });
          
          // 重新抛出错误，让调用方知道加载失败
          throw error;
        }
      },
      
      // 开始抽奖
      startDraw: async (studentId: string) => {
        console.log('🎲 Store: 开始抽奖');
        console.log('Store: 当前状态 - isDrawing:', get().isDrawing, 'drawResult:', get().drawResult);
        
        // 防止并发调用
        if (get().isDrawing) {
          console.log('Store: 抽奖正在进行中，拒绝重复调用');
          return {
            success: false,
            message: '抽奖正在进行中，请稍候'
          };
        }
        
        set({ isDrawing: true, drawResult: null });
        console.log('Store: 状态更新 - isDrawing: true, drawResult: null');
        
        try {
          console.log('Store: 调用 lotteryService.drawLottery()');
          const result = await lotteryService.drawLottery(studentId);
          console.log('Store: 抽奖结果:', result);
          
          set({ 
            drawResult: result,
            isDrawing: false 
          });
          console.log('Store: 最终状态更新 - drawResult:', result, 'isDrawing: false');
          
          return result;
        } catch (error) {
          console.error('Store: 抽奖失败:', error);
          const errorResult = {
            success: false,
            message: '抽奖失败，请重试'
          };
          set({ drawResult: errorResult, isDrawing: false });
          console.log('Store: 错误状态更新 - isDrawing: false');
          return errorResult;
        }
      },
      
      // 重置抽奖
      resetDraw: () => {
        set({ 
          drawResult: null, 
          currentStudentId: '',
          isDrawing: false,
          drawMessage: ''
        });
      },
      
      // 加载系统配置
      loadSystemConfig: async () => {
        try {
          const apiService = ApiService.getInstance();
          const config = await apiService.getSystemConfig();
          set({ 
            systemConfig: config,
            maxDrawTimes: config?.max_draw_times || 1
          });
          console.log('系统配置已加载:', config);
          console.log('最大抽奖次数已更新为:', config?.max_draw_times || 1);
        } catch (error) {
          console.error('Load system config failed:', error);
          set({ 
            systemConfig: null,
            maxDrawTimes: 1
          });
        }
      },

      // 设置系统配置
      setSystemConfig: (config: SystemConfig | null) => {
        set({ 
          systemConfig: config,
          maxDrawTimes: config?.max_draw_times || 1
        });
        console.log('系统配置已更新:', config);
        console.log('最大抽奖次数已同步更新为:', config?.max_draw_times || 1);
      },
      
      // 动态概率计算函数 - 结合抽奖次数上限和剩余数量
      calculateDynamicProbabilities: (prizeList: Prize[]): ProbabilityInfo[] => {
        // 只考虑启用且有剩余数量的奖项
        const activePrizes = prizeList.filter(p => p.is_active && p.remainingQuantity > 0);
        
        if (activePrizes.length === 0) {
          return [];
        }

        const state = get();
        const maxDrawTimes = state.systemConfig?.max_draw_times || 1;
       
       // 计算启用奖项的总权重（只考虑启用的奖项）
       const totalWeight = activePrizes.reduce((sum, prize) => sum + prize.probability, 0);
       
       return activePrizes.map(prize => {
         // 基础概率计算
         let dynamicProbability = totalWeight > 0 ? (prize.probability / totalWeight) : 0;
         let adjustedForDrawLimit = false;
         
         // 结合抽奖次数上限调整概率
         if (maxDrawTimes > 0) {
           // 计算剩余奖品与最大抽奖次数的比例
           const remainingDrawOpportunities = prize.remainingQuantity;
           const maxPossibleDraws = maxDrawTimes;
           
           // 如果剩余奖品数量远小于可能的抽奖总次数，降低显示概率
           if (remainingDrawOpportunities < maxPossibleDraws * 0.1) {
             dynamicProbability *= (remainingDrawOpportunities / (maxPossibleDraws * 0.1));
             adjustedForDrawLimit = true;
           }
           
           // 如果接近抽奖次数上限，进一步调整概率显示
           if (remainingDrawOpportunities <= maxPossibleDraws * 0.05) {
             dynamicProbability *= 0.5; // 进一步降低显示概率
             adjustedForDrawLimit = true;
           }
         }
         
         const remainingRatio = prize.totalQuantity > 0 ? (prize.remainingQuantity / prize.totalQuantity) * 100 : 0;
         
         return {
           prize,
           dynamicProbability,
           remainingRatio,
           adjustedForDrawLimit
         };
       }).sort((a, b) => a.prize.level - b.prize.level);
     },
     
     // 检查认证状态
      checkAuthStatus: () => {
        const isAuth = authService.checkTokenAndHandleExpiry();
        const currentAuth = get().isAuthenticated;
        
        if (isAuth !== currentAuth) {
          set({ isAuthenticated: isAuth });
          console.log('认证状态已更新:', isAuth);
        }
      },
     
     // 自动刷新认证
      autoRefreshAuth: () => {
        if (authService.isAuthenticated()) {
          authService.autoRefreshToken();
        }
      },
      
      // 获取token剩余时间
      getTokenRemainingTime: () => {
        return authService.getTokenRemainingTime();
      },
      
      // 清理方法 - 防止内存泄漏
      cleanup: () => {
        console.log('Store cleanup - 开始清理资源');
        
        // 清理认证服务
        authService.cleanup();
        
        // 清理抽奖服务
        lotteryService.cleanup();
        
        // 清理事件服务
        eventService.cleanup();
        
        // 清理WebSocket服务
        const { websocketService } = require('../services/websocketService');
        websocketService.cleanup();
        
        console.log('Store cleanup - 资源清理完成');
      }
    };
  }
);