import { AgentConfig, AgentMessage, AgentStatus, AgentEvent, AgentEventListener } from './types';

export class Agent {
  private config: AgentConfig;
  private status: AgentStatus = 'idle';
  private listeners: Set<AgentEventListener> = new Set();
  private lastError: Error | null = null;
  private processingPromise: Promise<AgentMessage> | null = null;
  private autoResetTimer: NodeJS.Timeout | null = null;

  constructor(config: AgentConfig) {
    this.config = {
      maxProcessTime: 5000, // 默认5秒
      ...config
    };
  }

  get id(): string {
    return this.config.id;
  }

  get name(): string {
    return this.config.name;
  }

  get currentStatus(): AgentStatus {
    return this.status;
  }

  addEventListener(listener: AgentEventListener): void {
    this.listeners.add(listener);
  }

  removeEventListener(listener: AgentEventListener): void {
    this.listeners.delete(listener);
  }

  private emit(event: AgentEvent): void {
    this.listeners.forEach(listener => listener(event));
  }

  private setStatus(newStatus: AgentStatus): void {
    if (this.status !== newStatus) {
      this.status = newStatus;
      this.emit({
        type: 'status_change',
        payload: newStatus,
        timestamp: Date.now()
      });

      // 如果状态变为 error，设置自动重置定时器
      if (newStatus === 'error') {
        this.scheduleAutoReset();
      }
    }
  }

  private scheduleAutoReset(): void {
    if (this.autoResetTimer) {
      clearTimeout(this.autoResetTimer);
    }

    this.autoResetTimer = setTimeout(() => {
      this.reset();
    }, 1000); // 1秒后自动重置
  }

  private validateMessage(message: AgentMessage): void {
    if (!message.content || message.content.trim() === '') {
      throw new Error('消息内容不能为空');
    }

    if (!['command', 'response', 'error'].includes(message.type)) {
      throw new Error('无效的消息类型');
    }
  }

  async process(message: AgentMessage): Promise<AgentMessage> {
    try {
      // 输入验证
      this.validateMessage(message);

      // 检查是否正在处理其他请求
      if (this.processingPromise) {
        throw new Error('Agent is busy');
      }

      this.setStatus('busy');
      this.emit({
        type: 'message',
        payload: message,
        timestamp: Date.now()
      });

      // 创建超时Promise
      const timeoutPromise = new Promise<AgentMessage>((_, reject) => {
        const timeoutId = setTimeout(() => {
          reject(new Error('Processing timeout'));
          this.setStatus('error');
        }, this.config.maxProcessTime);
        timeoutId.unref?.(); // 在 Node.js 环境中防止进程挂起
      });

      // 创建处理Promise
      this.processingPromise = this.processMessage(message).then(response => {
        this.setStatus('idle');
        this.processingPromise = null;
        return response;
      }).catch(error => {
        this.setStatus('error');
        this.processingPromise = null;
        throw error;
      });

      // 等待处理完成或超时
      try {
        const response = await Promise.race([this.processingPromise, timeoutPromise]);
        return response;
      } catch (error) {
        this.processingPromise = null;
        throw error;
      }

    } catch (error) {
      this.lastError = error as Error;
      this.setStatus('error');
      
      this.emit({
        type: 'error',
        payload: error,
        timestamp: Date.now()
      });

      return {
        type: 'error',
        content: error instanceof Error ? error.message : '未知错误',
        timestamp: Date.now()
      };
    }
  }

  private async processMessage(message: AgentMessage): Promise<AgentMessage> {
    // 模拟处理延迟
    await new Promise(resolve => setTimeout(resolve, 100));

    return {
      type: 'response',
      content: `处理消息: ${message.content}`,
      timestamp: Date.now(),
      metadata: {
        processingTime: Date.now() - (message.timestamp || Date.now())
      }
    };
  }

  async getLastError(): Promise<Error | null> {
    return this.lastError;
  }

  async reset(): Promise<void> {
    if (this.autoResetTimer) {
      clearTimeout(this.autoResetTimer);
      this.autoResetTimer = null;
    }

    this.setStatus('idle');
    this.lastError = null;
    this.processingPromise = null;
  }

  // 清理资源
  destroy(): void {
    if (this.autoResetTimer) {
      clearTimeout(this.autoResetTimer);
      this.autoResetTimer = null;
    }
    this.listeners.clear();
  }
} 