import { logger } from '../utils/logger';

export interface WebSocketMessage {
  type: 'NEW_MESSAGE' | 'pong' | 'ping';
  data?: {
    id: number;
    type: 'MESSAGE' | 'NOTIFICATION';
    content_type?: 'TEXT' | 'IMAGE' | 'VIDEO' | 'FILE' | 'USER_NOTIFICATION';
    title?: string;
    content: string;
    action_url?: string;
    action_text?: string;
    created_at: string;
    sender_id?: number;
    receiver_id?: number;
    size?: number;
  };
}

export class WebSocketService {
  private socket: WebSocket | null = null;
  private token: string;
  private onMessage: (data: WebSocketMessage['data']) => void;
  private pingInterval: NodeJS.Timeout | null = null;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 5;
  private reconnectDelay = 3000; // 3秒

  constructor(token: string, onMessage: (data: WebSocketMessage['data']) => void) {
    this.token = token;
    this.onMessage = onMessage;
  }

  connect() {
    // 判断是否在开发环境，如果是则使用代理
    const isDev = import.meta.env.DEV;
    let wsUrl: string;
    let safeUrl: string;
    
    if (isDev) {
      // 开发环境：通过 Vite 代理连接（需要配置 ws: true）
      // 注意：Vite 的 HTTP 代理默认不支持 WebSocket，需要单独配置
      // 这里先尝试直接连接，如果失败可能需要配置代理
      const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
      wsUrl = `${protocol}//${window.location.host}/api/v1/ws/messages?token=${this.token}`;
      safeUrl = `${protocol}//${window.location.host}/api/v1/ws/messages?token=***`;
    } else {
      // 生产环境：直接连接
      wsUrl = `wss://api.hnyunzhu.com/api/v1/ws/messages?token=${this.token}`;
      safeUrl = `wss://api.hnyunzhu.com/api/v1/ws/messages?token=***`;
    }
    
    logger.info('WS: Connecting...', { 
      url: safeUrl,
      isDev,
      protocol: isDev ? (window.location.protocol === 'https:' ? 'wss' : 'ws') : 'wss'
    });
    
    try {
      this.socket = new WebSocket(wsUrl);
      this.setupEventHandlers();
    } catch (error) {
      logger.error('WS: Connection error (catch)', { 
        error: error instanceof Error ? error.message : String(error),
        url: safeUrl,
        isDev
      });
      this.scheduleReconnect();
    }
  }

  private setupEventHandlers() {
    if (!this.socket) return;

    this.socket.onopen = () => {
      logger.info('WS: Connected');
      this.reconnectAttempts = 0;
      
      // 启动心跳机制：每30秒发送一次 ping
      this.startHeartbeat();
    };

    this.socket.onmessage = (event) => {
      try {
        // 处理文本消息
        if (typeof event.data === 'string') {
          // 处理心跳响应（直接是字符串 'pong'）
          if (event.data === 'pong') {
            logger.info('WS: Received pong');
            return;
          }
          
          // 解析 JSON 消息
          const payload: WebSocketMessage = JSON.parse(event.data);
          logger.info('WS: Received message', { 
            type: payload.type, 
            hasData: !!payload.data,
            data: payload.data 
          });
          
          // 处理新消息
          if (payload.type === 'NEW_MESSAGE' && payload.data) {
            logger.info('WS: Calling onMessage callback', payload.data);
            this.onMessage(payload.data);
          } else {
            logger.warn('WS: Unknown message type or missing data', payload);
          }
        } else {
          logger.warn('WS: Received non-text message', { dataType: typeof event.data });
        }
      } catch (e) {
        logger.error('WS: Parse error', { error: e, data: event.data });
      }
    };

    this.socket.onclose = (event) => {
      const closeInfo: any = {
        code: event.code,
        reason: event.reason || 'No reason provided',
        wasClean: event.wasClean
      };
      
      // WebSocket 关闭代码说明
      const closeCodeMap: Record<number, string> = {
        1000: 'Normal Closure',
        1001: 'Going Away',
        1002: 'Protocol Error',
        1003: 'Unsupported Data',
        1006: 'Abnormal Closure (no close frame)',
        1007: 'Invalid Data',
        1008: 'Policy Violation',
        1009: 'Message Too Big',
        1010: 'Missing Extension',
        1011: 'Internal Error',
        1012: 'Service Restart',
        1013: 'Try Again Later',
        1014: 'Bad Gateway',
        1015: 'TLS Handshake Failed'
      };
      
      closeInfo.codeDescription = closeCodeMap[event.code] || 'Unknown';
      
      // 如果 code 是 0，可能是连接从未建立
      if (event.code === 0) {
        closeInfo.codeDescription = 'Connection never established (possibly network/SSL error)';
      }
      
      logger.warn('WS: Disconnected', closeInfo);
      this.stopHeartbeat();
      
      // 如果不是正常关闭，尝试重连
      if (event.code !== 1000 && this.reconnectAttempts < this.maxReconnectAttempts) {
        this.scheduleReconnect();
      } else if (event.code === 1000) {
        logger.info('WS: Normal closure, will not reconnect');
      }
    };

    this.socket.onerror = (err) => {
      const errorInfo: any = {
        readyState: this.socket?.readyState,
        readyStateText: this.socket?.readyState === WebSocket.CONNECTING ? 'CONNECTING' :
                       this.socket?.readyState === WebSocket.OPEN ? 'OPEN' :
                       this.socket?.readyState === WebSocket.CLOSING ? 'CLOSING' :
                       this.socket?.readyState === WebSocket.CLOSED ? 'CLOSED' : 'UNKNOWN'
      };
      
      // 尝试获取更多错误信息
      if (err instanceof Error) {
        errorInfo.message = err.message;
        errorInfo.stack = err.stack;
      } else if (err && typeof err === 'object') {
        // 如果是 Event 对象，尝试获取更多信息
        errorInfo.type = (err as any).type;
        errorInfo.target = (err as any).target ? {
          readyState: (err as any).target.readyState,
          url: (err as any).target.url ? (err as any).target.url.replace(/token=[^&]+/, 'token=***') : undefined
        } : undefined;
      }
      
      logger.error('WS: Connection error (onerror)', errorInfo);
      
      // 如果是连接错误，安排重连
      if (this.socket?.readyState === WebSocket.CLOSED || this.socket?.readyState === WebSocket.CLOSING) {
        if (this.reconnectAttempts < this.maxReconnectAttempts) {
          this.scheduleReconnect();
        }
      }
    };
  }

  /**
   * 启动心跳机制
   * 客户端每30秒发送一次 ping，服务端回复 pong
   */
  private startHeartbeat() {
    this.stopHeartbeat();
    
    this.pingInterval = setInterval(() => {
      if (this.socket && this.socket.readyState === WebSocket.OPEN) {
        try {
          // 发送 ping 消息（直接发送字符串，不是 JSON）
          this.socket.send('ping');
          logger.info('WS: Sent ping');
        } catch (error) {
          logger.error('WS: Failed to send ping', error);
        }
      }
    }, 30000); // 30秒
  }

  /**
   * 停止心跳机制
   */
  private stopHeartbeat() {
    if (this.pingInterval) {
      clearInterval(this.pingInterval);
      this.pingInterval = null;
    }
  }

  /**
   * 安排重连
   */
  private scheduleReconnect() {
    this.reconnectAttempts++;
    const delay = this.reconnectDelay * this.reconnectAttempts;
    
    logger.info(`WS: Scheduling reconnect attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts} in ${delay}ms`);
    
    setTimeout(() => {
      if (this.reconnectAttempts <= this.maxReconnectAttempts) {
        this.connect();
      } else {
        logger.error('WS: Max reconnect attempts reached');
      }
    }, delay);
  }

  /**
   * 手动发送消息（如果需要）
   */
  send(data: any) {
    if (this.socket && this.socket.readyState === WebSocket.OPEN) {
      this.socket.send(JSON.stringify(data));
    } else {
      logger.warn('WS: Cannot send message, socket not open');
    }
  }

  /**
   * 断开连接
   */
  disconnect() {
    this.stopHeartbeat();
    if (this.socket) {
      this.socket.close(1000, 'Client disconnect');
      this.socket = null;
    }
  }

  /**
   * 获取连接状态
   */
  isConnected(): boolean {
    return this.socket !== null && this.socket.readyState === WebSocket.OPEN;
  }
}
