"use client";

import { create } from "zustand";

export type NetworkMode = "websocket" | "polling" | "offline";

export type NetworkConnectionState = {
  /** 当前网络模式：WebSocket 正常 / 降级轮询 / 离线 */
  mode: NetworkMode;
  /** WebSocket 是否已连接 */
  isWebSocketConnected: boolean;
  /** 是否正在尝试重连 */
  isReconnecting: boolean;
  /** 重连尝试次数 */
  reconnectAttempts: number;
  /** 上次连接成功时间 */
  lastConnectedAt: number | null;
  /** 上次断开连接时间 */
  lastDisconnectedAt: number | null;
  /** 当前活跃的画作数据轮询计时器ID */
  drawPollingIntervalId: number | null;
  /** 当前活跃的钱包余额轮询计时器ID */
  walletPollingIntervalId: number | null;
  /** 钱包余额轮询过期时间戳（用于bet后的限时轮询） */
  walletPollingExpiryAt: number | null;

  // Actions
  setMode: (mode: NetworkMode) => void;
  setWebSocketConnected: (connected: boolean) => void;
  setReconnecting: (reconnecting: boolean) => void;
  incrementReconnectAttempts: () => void;
  resetReconnectAttempts: () => void;
  setLastConnectedAt: (timestamp: number | null) => void;
  setLastDisconnectedAt: (timestamp: number | null) => void;
  setDrawPollingIntervalId: (id: number | null) => void;
  setWalletPollingIntervalId: (id: number | null) => void;
  setWalletPollingExpiryAt: (timestamp: number | null) => void;
  /** 切换到降级模式（WebSocket断开时调用） */
  switchToPollingMode: () => void;
  /** 切换回WebSocket模式（WebSocket重连成功时调用） */
  switchToWebSocketMode: () => void;
  /** 清除所有轮询计时器 */
  clearAllPollingIntervals: () => void;
  /** 停止钱包轮询 */
  clearWalletPolling: () => void;
  /** 停止画作数据轮询 */
  clearDrawPolling: () => void;
};

export const useNetworkConnectionStore = create<NetworkConnectionState>(
  (set, get) => ({
    mode: "websocket",
    isWebSocketConnected: false,
    isReconnecting: false,
    reconnectAttempts: 0,
    lastConnectedAt: null,
    lastDisconnectedAt: null,
    drawPollingIntervalId: null,
    walletPollingIntervalId: null,
    walletPollingExpiryAt: null,

    setMode: (mode) => set({ mode }),

    setWebSocketConnected: (connected) =>
      set({ isWebSocketConnected: connected }),

    setReconnecting: (reconnecting) => set({ isReconnecting: reconnecting }),

    incrementReconnectAttempts: () =>
      set((state) => ({ reconnectAttempts: state.reconnectAttempts + 1 })),

    resetReconnectAttempts: () => set({ reconnectAttempts: 0 }),

    setLastConnectedAt: (timestamp) => set({ lastConnectedAt: timestamp }),

    setLastDisconnectedAt: (timestamp) =>
      set({ lastDisconnectedAt: timestamp }),

    setDrawPollingIntervalId: (id) => set({ drawPollingIntervalId: id }),

    setWalletPollingIntervalId: (id) => set({ walletPollingIntervalId: id }),

    setWalletPollingExpiryAt: (timestamp) =>
      set({ walletPollingExpiryAt: timestamp }),

    switchToPollingMode: () =>
      set({
        mode: "polling",
        isWebSocketConnected: false,
        lastDisconnectedAt: Date.now(),
      }),

    switchToWebSocketMode: () => {
      const { drawPollingIntervalId, walletPollingIntervalId } = get();
      // 清除轮询计时器
      if (drawPollingIntervalId) {
        window.clearInterval(drawPollingIntervalId);
      }
      if (walletPollingIntervalId) {
        window.clearInterval(walletPollingIntervalId);
      }
      set({
        mode: "websocket",
        isWebSocketConnected: true,
        lastConnectedAt: Date.now(),
        drawPollingIntervalId: null,
        walletPollingIntervalId: null,
        walletPollingExpiryAt: null,
        reconnectAttempts: 0,
        isReconnecting: false,
      });
    },

    clearAllPollingIntervals: () => {
      const { drawPollingIntervalId, walletPollingIntervalId } = get();
      if (drawPollingIntervalId) {
        window.clearInterval(drawPollingIntervalId);
      }
      if (walletPollingIntervalId) {
        window.clearInterval(walletPollingIntervalId);
      }
      set({
        drawPollingIntervalId: null,
        walletPollingIntervalId: null,
        walletPollingExpiryAt: null,
      });
    },

    clearWalletPolling: () => {
      const { walletPollingIntervalId } = get();
      if (walletPollingIntervalId) {
        window.clearInterval(walletPollingIntervalId);
      }
      set({
        walletPollingIntervalId: null,
        walletPollingExpiryAt: null,
      });
    },

    clearDrawPolling: () => {
      const { drawPollingIntervalId } = get();
      if (drawPollingIntervalId) {
        window.clearInterval(drawPollingIntervalId);
      }
      set({ drawPollingIntervalId: null });
    },
  }),
);
