/**
 * TUI Application
 *
 * 主 TUI 应用，整合所有组件
 */

import blessed from 'blessed';
import type { Widgets } from 'blessed';
import type { APIClient, Session, Message } from '../client/api.js';
import { ChatView, SessionList, StatusBar } from './components/index.js';
import type { ChatMessage, TUIConfig } from './types.js';

export class TUIApp {
  private screen: Widgets.Screen;
  private client: APIClient;
  private sessionList: SessionList;
  private chatView: ChatView;
  private statusBar: StatusBar;

  private currentSession: Session | null = null;
  private ws: WebSocket | null = null;
  private focusTarget: 'sessions' | 'chat' = 'sessions';

  constructor(config: TUIConfig) {
    this.client = config.client;

    // 创建屏幕
    this.screen = blessed.screen({
      smartCSR: true,
      title: 'AI Terminal Assistant',
      cursor: {
        artificial: true,
        shape: 'line',
        blink: true,
        color: 'white',
      },
    });

    // 创建组件
    this.sessionList = new SessionList({
      parent: this.screen,
      left: 0,
      top: 0,
      width: '25%',
      height: '100%-1',
    });

    this.chatView = new ChatView({
      parent: this.screen,
      left: '25%',
      top: 0,
      width: '75%',
      height: '100%-1',
    });

    this.statusBar = new StatusBar({
      parent: this.screen,
      bottom: 0,
    });

    this.setupCallbacks();
    this.setupKeyBindings();

    // 如果有初始 sessionId，连接到该会话
    if (config.sessionId) {
      this.connectToSession(config.sessionId);
    }
  }

  /**
   * 设置组件回调
   */
  private setupCallbacks(): void {
    // 会话列表回调
    this.sessionList.setOnSelect((session) => {
      this.connectToSession(session.id);
    });

    this.sessionList.setOnCreate(async () => {
      await this.createSession();
    });

    this.sessionList.setOnDelete(async (session) => {
      await this.deleteSession(session);
    });

    // 聊天视图回调
    this.chatView.setOnSend((content) => {
      this.sendMessage(content);
    });
  }

  /**
   * 设置全局快捷键
   */
  private setupKeyBindings(): void {
    // 退出
    this.screen.key(['q', 'C-c'], () => {
      this.quit();
    });

    // Tab 切换焦点
    this.screen.key('tab', () => {
      this.toggleFocus();
    });

    // Escape 切换到会话列表
    this.screen.key('escape', () => {
      this.focusTarget = 'sessions';
      this.sessionList.focus();
      this.screen.render();
    });
  }

  /**
   * 切换焦点
   */
  private toggleFocus(): void {
    if (this.focusTarget === 'sessions') {
      this.focusTarget = 'chat';
      this.chatView.focus();
    } else {
      this.focusTarget = 'sessions';
      this.sessionList.focus();
    }
    this.screen.render();
  }

  /**
   * 启动应用
   */
  async start(): Promise<void> {
    // 获取服务器健康状态
    try {
      const health = await this.client.health();
      this.statusBar.setStatus({
        serverUrl: (this.client as any).baseUrl,
        connected: true,
        agentAvailable: health.agent.coreAvailable,
      });
    } catch {
      this.statusBar.setStatus({
        connected: false,
      });
    }

    // 加载会话列表
    await this.loadSessions();

    // 聚焦会话列表
    this.sessionList.focus();
    this.screen.render();
  }

  /**
   * 加载会话列表
   */
  private async loadSessions(): Promise<void> {
    try {
      const { data: sessions } = await this.client.listSessions();
      this.sessionList.setSessions(sessions);
    } catch (error) {
      this.showError('Failed to load sessions');
    }
  }

  /**
   * 创建新会话
   */
  private async createSession(): Promise<void> {
    try {
      const { data: session } = await this.client.createSession();
      await this.loadSessions();
      this.connectToSession(session.id);
    } catch (error) {
      this.showError('Failed to create session');
    }
  }

  /**
   * 删除会话
   */
  private async deleteSession(session: Session): Promise<void> {
    try {
      await this.client.deleteSession(session.id);
      if (this.currentSession?.id === session.id) {
        this.disconnectWebSocket();
        this.currentSession = null;
        this.chatView.clearMessages();
        this.statusBar.setStatus({ sessionId: undefined, sessionName: undefined });
      }
      await this.loadSessions();
    } catch (error) {
      this.showError('Failed to delete session');
    }
  }

  /**
   * 连接到会话
   */
  private async connectToSession(sessionId: string): Promise<void> {
    // 断开现有连接
    this.disconnectWebSocket();

    try {
      // 获取会话信息
      const { data: session } = await this.client.getSession(sessionId);
      this.currentSession = session;

      // 更新状态栏
      this.statusBar.setStatus({
        sessionId: session.id,
        sessionName: session.name,
      });

      // 高亮选中的会话
      this.sessionList.selectSession(sessionId);

      // 加载历史消息
      const { data: messages } = await this.client.getMessages(sessionId);
      this.chatView.setMessages(
        messages.map((m) => this.toDisplayMessage(m))
      );

      // 连接 WebSocket
      this.connectWebSocket(sessionId);

      // 切换焦点到聊天视图
      this.focusTarget = 'chat';
      this.chatView.focus();
      this.screen.render();
    } catch (error) {
      this.showError('Failed to connect to session');
    }
  }

  /**
   * 连接 WebSocket
   */
  private connectWebSocket(sessionId: string): void {
    this.ws = this.client.connectWebSocket(sessionId);

    this.ws.onopen = () => {
      this.statusBar.setStatus({ connected: true });
    };

    this.ws.onmessage = (event) => {
      try {
        const message = JSON.parse(event.data as string);
        this.handleWebSocketMessage(message);
      } catch {
        // 忽略解析错误
      }
    };

    this.ws.onerror = () => {
      this.showError('WebSocket error');
    };

    this.ws.onclose = () => {
      this.ws = null;
    };
  }

  /**
   * 断开 WebSocket
   */
  private disconnectWebSocket(): void {
    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
  }

  /**
   * 处理 WebSocket 消息
   */
  private handleWebSocketMessage(message: { type: string; payload?: any }): void {
    switch (message.type) {
      case 'chunk':
        this.chatView.appendStreamingContent(message.payload?.content || '');
        break;

      case 'done':
        if (message.payload?.message) {
          this.chatView.finishStreaming(this.toDisplayMessage(message.payload.message));
        }
        // 刷新会话列表以更新消息计数
        this.loadSessions();
        break;

      case 'error':
        this.showError(message.payload?.message || 'Unknown error');
        break;
    }
  }

  /**
   * 发送消息
   */
  private sendMessage(content: string): void {
    if (!this.ws || !this.currentSession) {
      this.showError('Not connected to a session');
      return;
    }

    // 添加用户消息到视图
    this.chatView.addMessage({
      id: Date.now().toString(),
      role: 'user',
      content,
      timestamp: new Date().toISOString(),
    });

    // 通过 WebSocket 发送
    this.ws.send(JSON.stringify({
      type: 'message',
      sessionId: this.currentSession.id,
      payload: { content },
    }));
  }

  /**
   * 转换消息格式
   */
  private toDisplayMessage(message: Message): ChatMessage {
    return {
      id: message.id,
      role: message.role,
      content: message.content,
      timestamp: message.timestamp,
    };
  }

  /**
   * 显示错误
   */
  private showError(message: string): void {
    const dialog = blessed.message({
      parent: this.screen,
      border: 'line',
      height: 'shrink',
      width: 'half',
      top: 'center',
      left: 'center',
      label: ' Error ',
      tags: true,
      style: {
        border: { fg: 'red' },
        label: { fg: 'red', bold: true },
      },
    });

    dialog.error(message, () => {
      dialog.destroy();
      this.screen.render();
    });
  }

  /**
   * 退出应用
   */
  quit(): void {
    this.disconnectWebSocket();
    this.screen.destroy();
    process.exit(0);
  }
}
