import { Component, OnInit, OnDestroy } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment';
import { v4 as uuidv4 } from 'uuid';

export interface IServerMessage {
  header?: {
    code?: number;
    message?: string;
    sid?: string;
    status?: number;
    type?: 'heartbeat_ack' | 'normal'; // 在header中定义类型字段
  };
  payload?: {
    type?: 'heartbeat_ack' | 'normal'; // 在payload中也定义类型字段
    choices?: {
      text?: Array<{
        content: string;
        role: 'user' | 'assistant';
        index?: number;
      }>;
    };
  };
}

@Component({
  selector: 'app-tab2',
  templateUrl: './tab2.page.html',
  styleUrls: ['./tab2.page.scss'],
})
export class Tab2Page implements OnInit, OnDestroy {
  messages: any[] = [];
  userInput: string = '';
  isLoading: boolean = false;
  private socket: WebSocket | null = null;
  private messageBuffers: Map<string, { content: string[], status: number }> = new Map();
  private activeSessions: Set<string> = new Set();
  private heartbeatInterval: number = 30000; // 每30秒发送一次心跳
  private heartbeatTimer: any;
  private serverAcknowledgeTimeout: any;

  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.sendMessageFromAI(this.getRandomWelcomeMessage());
    this.initWebSocket();
  }

  ngOnDestroy() {
    // 不要在这里手动关闭连接
    // if (this.socket) {
    //   if (this.activeSessions.size > 0) {
    //     console.warn('There are active sessions, attempting graceful shutdown...');
    //     setTimeout(() => {
    //       if (this.socket) {
    //         this.socket.close();
    //       }
    //     }, 5000); // 假设5秒足够让服务器处理完所有请求
    //   } else {
    //     console.log('No active sessions, closing WebSocket immediately.');
    //     this.socket.close();
    //   }
    // }
  }

  get isSocketOpen(): boolean {
    return Boolean(this.socket && this.socket.readyState === WebSocket.OPEN);
  }

  getRandomWelcomeMessage(): string {
    const welcomeMessages = [
      '我是您的AI医生小爱，有什么可以帮到您的吗？',
      '今天天气不错，可以出去散步哦。',
      '您好！我是您的健康助手，有什么我可以帮助您的吗？',
      '很高兴见到您！请告诉我您需要什么帮助。',
      '欢迎您！请问有什么健康方面的问题需要咨询吗？'
    ];
    return welcomeMessages[Math.floor(Math.random() * welcomeMessages.length)];
  }

  async initWebSocket() {
    try {
      const response = await this.http.get(environment.apiUrl + '/api/v1/getWebSocketUrl', { responseType: 'text' }).toPromise();
      const wsUrl = response as string;

      if (!wsUrl || wsUrl.trim().length === 0) {
        throw new Error('Received an empty or undefined WebSocket URL');
      }

      console.log('Fetched WebSocket URL:', wsUrl);

      this.socket = new WebSocket(wsUrl);

      this.socket.onopen = () => {
        console.log('WebSocket connection opened');
        this.startHeartbeat();
      };

      this.socket.onmessage = (event) => {
        try {
          const message: IServerMessage = JSON.parse(event.data);
          console.log('Parsed message:', message);

          if (message.header?.code === 0) {
            // 检查心跳确认消息
            if (message.header?.type === 'heartbeat_ack' || message.payload?.type === 'heartbeat_ack') {
              this.resetHeartbeat();
              return; // 如果是心跳确认消息，不再继续处理其他逻辑
            }

            // 继续处理正常消息...
            if (
              message.payload &&
              message.payload.choices &&
              Array.isArray(message.payload.choices.text)
            ) {
              const sid = message.header?.sid || ''; // 提供默认值
              const status = message.header?.status || 0; // 提供默认值

              // 初始化或获取当前对话的缓冲区
              let buffer = this.messageBuffers.get(sid) || { content: [], status: 0 };
              buffer.status = status;

              // 累积所有非空文本内容，并去除前后空白字符
              buffer.content.push(
                ...message.payload.choices.text
                  .filter(item => typeof item.content === 'string' && item.content.trim() !== '')
                  .map(item => item.content.trim())
              );

              // 如果是最后一条消息，则合并并显示
              if (buffer.status === 2) {
                const combinedContent = buffer.content.join(' ');
                const cleanedContent = combinedContent.replace(/\s+/g, ' ').trim();

                this.sendMessageFromAI(cleanedContent); // 一次性发送合并后的内容
                this.messageBuffers.delete(sid); // 清除已完成会话的缓冲区
                this.activeSessions.delete(sid); // 从活跃会话中移除

                // 检查是否还有活跃会话
                if (this.activeSessions.size === 0) {
                  this.isLoading = false;
                }
              } else {
                // 更新缓冲区
                this.messageBuffers.set(sid, buffer);
              }
            } else {
              console.error('Invalid or unexpected message format:', message);
              this.sendMessageFromAI('收到的消息格式无效，请检查服务器配置。');
              this.isLoading = false;
            }
          } 
        } catch (error) {
          console.error('Error parsing message:', error);
          this.sendMessageFromAI('抱歉，系统出现错误，请稍后再试。');
          this.isLoading = false;
        }
      };

      this.socket.onerror = (event) => {
        console.error('WebSocket error observed:', event);
        this.sendMessageFromAI('抱歉，系统出现错误，请稍后再试。');
        this.isLoading = false;
      };

      this.socket.onclose = (event) => {
        console.log('WebSocket connection closed:', event);
        this.reconnectWebSocket(); // 尝试重新连接
        this.isLoading = false;
      };
    } catch (error) {
      console.error('Failed to fetch WebSocket URL:', error);
      this.sendMessageFromAI('无法获取WebSocket连接信息，请检查网络设置。');
    }
  }

  private startHeartbeat() {
    this.stopHeartbeat(); // 确保只有一个心跳计时器运行

    this.heartbeatTimer = setInterval(() => {
      if (this.isSocketOpen) {
        this.sendHeartbeat();
      } else {
        this.stopHeartbeat();
      }
    }, this.heartbeatInterval);

    this.serverAcknowledgeTimeout = setTimeout(() => {
      console.warn('No heartbeat acknowledgment received from the server.');
      this.reconnectWebSocket(); // 尝试重新连接
    }, this.heartbeatInterval * 2); // 设置两倍的心跳间隔作为等待服务器回应的时间
  }

  private sendHeartbeat() {
    const heartbeatMessage = {
      header: {
        type: 'heartbeat'
      },
      payload: {}
    };
    console.log('Sending heartbeat...');
    this.socket!.send(JSON.stringify(heartbeatMessage));
  }

  private resetHeartbeat() {
    clearTimeout(this.serverAcknowledgeTimeout);
    this.serverAcknowledgeTimeout = setTimeout(() => {
      console.warn('No heartbeat acknowledgment received from the server.');
      this.reconnectWebSocket(); // 尝试重新连接
    }, this.heartbeatInterval * 2); // 再次设置两倍的心跳间隔作为等待服务器回应的时间
  }

  private stopHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer);
      this.heartbeatTimer = undefined;
    }
    if (this.serverAcknowledgeTimeout) {
      clearTimeout(this.serverAcknowledgeTimeout);
      this.serverAcknowledgeTimeout = undefined;
    }
  }

  private reconnectWebSocket() {
    console.log('Attempting to reconnect WebSocket...');
    this.stopHeartbeat();
    if (this.socket) {
      this.socket.close();
    }
    this.initWebSocket();
  }

  private handleIncomingMessage(event: MessageEvent<string>) {
    try {
      const message: IServerMessage = JSON.parse(event.data);
      console.log('Parsed message:', message);

      if (
        message.header &&
        message.header.code === 0 &&
        message.payload &&
        message.payload.choices &&
        Array.isArray(message.payload.choices.text)
      ) {
        const sid = message.header.sid || ''; // 提供默认值
        const status = message.header.status || 0; // 提供默认值

        // 初始化或获取当前对话的缓冲区
        let buffer = this.messageBuffers.get(sid) || { content: [], status: 0 };
        buffer.status = status;

        // 累积所有非空文本内容，并去除前后空白字符
        buffer.content.push(
          ...message.payload.choices.text
            .filter(item => typeof item.content === 'string' && item.content.trim() !== '')
            .map(item => item.content.trim())
        );

        // 如果是最后一条消息，则合并并显示
        if (buffer.status === 2) {
          // 使用单个空格作为分隔符连接文本片段，或者根据需要选择其他分隔符
          const combinedContent = buffer.content.join(' ');

          // 去除最终结果中的多余空白字符
          const cleanedContent = combinedContent.replace(/\s+/g, ' ').trim();

          this.sendMessageFromAI(cleanedContent); // 一次性发送合并后的内容
          this.messageBuffers.delete(sid); // 清除已完成会话的缓冲区
          this.activeSessions.delete(sid); // 从活跃会话中移除

          // 检查是否还有活跃会话
          if (this.activeSessions.size === 0) {
            this.isLoading = false;
          }
        } else {
          // 更新缓冲区
          this.messageBuffers.set(sid, buffer);
        }
      } else {
        console.error('Invalid or unexpected message format:', message);
        this.sendMessageFromAI('收到的消息格式无效，请检查服务器配置。');
        this.isLoading = false;
      }
    } catch (error) {
      console.error('Error parsing message:', error);
      this.sendMessageFromAI('抱歉，系统出现错误，请稍后再试。');
      this.isLoading = false;
    }
  }

  sendMessage() {
    const trimmedInput = this.userInput.trim();
    if (!trimmedInput) {
      alert('请输入您的问题或消息'); 
      return;
    }

    this.messages.push({ text: trimmedInput, sender: 'user' });
    this.isLoading = true;
    this.userInput = '';

    if (this.isSocketOpen) {
      const uid = localStorage.getItem('user_id') || uuidv4();
      localStorage.setItem('user_id', uid);

      const sendMessage = {
        header: {
          app_id: "c907b21b",
          uid,
        },
        parameter: {
          chat: {
            domain: "generalv3.5",
            temperature: 0.5,
            max_tokens: 4096,
          }
        },
        payload: {
          message: {
            text: [{
              content: trimmedInput,
              role: 'user'
            }]
          }
        }
      };

      this.socket!.send(JSON.stringify(sendMessage));
      this.activeSessions.add(uid);
    } else {
      this.sendMessageFromAI('WebSocket 连接已断开，请稍后再试。');
      this.isLoading = false;
    }
  }

  private sendMessageFromAI(content: string) {
    this.messages.push({ text: content, sender: 'ai' });
  }
}