import type { ModelMessage } from 'ai';
import * as storage from './storage/index.js';
import { SessionStorage, MessageStorage, PartStorage, TodoStorage } from './storage/index.js';
import type { SessionInfo, Part, TodoItem } from './storage/index.js';
import { generateSessionId } from './id.js';
import { getProjectId, isGitRepository } from './project.js';

/**
 * 会话摘要（用于列表展示）
 */
export interface SessionSummary {
  id: string;
  title: string;
  workdir: string;
  messageCount: number;
  createdAt: string;
  updatedAt: string;
}

/**
 * 运行时会话数据（兼容旧接口）
 */
export interface SessionData {
  id: string;
  projectId: string;
  parentId?: string;
  agentName?: string;
  createdAt: string;
  updatedAt: string;
  workdir: string;
  title?: string;
  messages: ModelMessage[];
  discoveredTools: string[];
  todos: TodoItem[];
}

/**
 * 项目元数据
 */
export interface ProjectMetadata {
  id: string;
  workdir: string;
  createdAt: string;
  isGitRepo: boolean;
}

/**
 * 会话管理器
 * 提供高级会话操作接口，使用新的三层存储结构
 */
export class SessionManager {
  private currentSession: SessionData | null = null;
  private currentProject: ProjectMetadata | null = null;
  private autoSaveInterval: ReturnType<typeof setInterval> | null = null;
  private storageDir?: string;

  constructor(storageDir?: string) {
    this.storageDir = storageDir;
  }

  /**
   * 初始化 - 尝试恢复或创建新会话
   */
  async init(workdir: string): Promise<SessionData> {
    // 初始化存储
    await storage.initStorage(this.storageDir);

    // 获取或创建项目
    this.currentProject = await this.getOrCreateProject(workdir);

    // 尝试加载当前会话
    const currentSessionId = await this.getCurrentSessionId();

    if (currentSessionId) {
      const existing = await this.loadSession(this.currentProject.id, currentSessionId);

      if (existing && existing.workdir === workdir) {
        this.currentSession = existing;
        this.startAutoSave();
        return this.currentSession;
      }
    }

    // 创建新会话
    this.currentSession = await this.createNewSession(workdir);
    await this.saveSessionInfo();
    await this.setCurrentSessionPointer(this.currentSession.id);

    this.startAutoSave();
    return this.currentSession;
  }

  /**
   * 获取或创建项目
   */
  private async getOrCreateProject(workdir: string): Promise<ProjectMetadata> {
    const projectId = await getProjectId(workdir);

    try {
      const existing = await storage.read<ProjectMetadata>(['project', projectId]);
      return existing;
    } catch (e) {
      if (e instanceof storage.StorageNotFoundError) {
        const isGitRepo = await isGitRepository(workdir);
        const project: ProjectMetadata = {
          id: projectId,
          workdir,
          createdAt: new Date().toISOString(),
          isGitRepo,
        };
        await storage.write(['project', projectId], project);
        return project;
      }
      throw e;
    }
  }

  /**
   * 创建新会话
   */
  private async createNewSession(workdir: string): Promise<SessionData> {
    if (!this.currentProject) {
      throw new Error('Project not initialized. Call init() first.');
    }

    const sessionInfo = await SessionStorage.create(this.currentProject.id, workdir);

    return {
      id: sessionInfo.id,
      projectId: sessionInfo.projectId,
      createdAt: new Date(sessionInfo.createdAt).toISOString(),
      updatedAt: new Date(sessionInfo.updatedAt).toISOString(),
      workdir: sessionInfo.workdir,
      title: sessionInfo.title,
      messages: [],
      discoveredTools: sessionInfo.discoveredTools,
      todos: [],
    };
  }

  /**
   * 加载会话（从存储重建）
   */
  private async loadSession(projectId: string, sessionId: string): Promise<SessionData | null> {
    const sessionInfo = await SessionStorage.get(projectId, sessionId);
    if (!sessionInfo) return null;

    // 加载消息
    const messages = await this.loadMessagesFromStorage(sessionId);

    // 加载 todos
    const todoList = await TodoStorage.get(sessionId);

    return {
      id: sessionInfo.id,
      projectId: sessionInfo.projectId,
      parentId: sessionInfo.parentId,
      agentName: sessionInfo.agentName,
      createdAt: new Date(sessionInfo.createdAt).toISOString(),
      updatedAt: new Date(sessionInfo.updatedAt).toISOString(),
      workdir: sessionInfo.workdir,
      title: sessionInfo.title,
      messages,
      discoveredTools: sessionInfo.discoveredTools,
      todos: todoList?.items || [],
    };
  }

  /**
   * 从存储加载消息并转换为 AI SDK 格式
   */
  private async loadMessagesFromStorage(sessionId: string): Promise<ModelMessage[]> {
    const messageInfos = await MessageStorage.listBySession(sessionId);
    const messages: ModelMessage[] = [];

    for (const messageInfo of messageInfos) {
      const parts = await PartStorage.getByIds(messageInfo.id, messageInfo.partIds);
      const modelMessage = this.partsToModelMessage(messageInfo.role, parts);
      if (modelMessage) {
        messages.push(modelMessage);
      }
    }

    return messages;
  }

  /**
   * 将 Parts 转换为 AI SDK ModelMessage
   */
  private partsToModelMessage(role: string, parts: Part[]): ModelMessage | null {
    if (parts.length === 0) return null;

    // 构建消息内容
    const content: unknown[] = [];

    for (const part of parts) {
      switch (part.type) {
        case 'text':
          content.push({ type: 'text', text: part.text });
          break;
        case 'tool':
          if (role === 'assistant') {
            content.push({
              type: 'tool-call',
              toolCallId: part.toolCallId,
              toolName: part.toolName,
              args: part.args,
            });
          } else if (role === 'tool') {
            // Tool result message - AI SDK 的 tool message 格式
            return {
              role: 'tool',
              content: [{
                type: 'tool-result',
                toolCallId: part.toolCallId,
                toolName: part.toolName,
                result: part.result,
              }],
            } as unknown as ModelMessage;
          }
          break;
        case 'file':
          content.push({
            type: 'image',
            image: part.data,
            mimeType: part.mimeType,
          });
          break;
        case 'reasoning':
          // Reasoning 通常作为文本的一部分
          content.push({ type: 'text', text: `[Reasoning] ${part.text}` });
          break;
      }
    }

    // 简化：如果只有一个文本内容，直接使用字符串
    if (content.length === 1 && (content[0] as { type: string }).type === 'text') {
      return {
        role: role as 'user' | 'assistant' | 'system',
        content: (content[0] as { text: string }).text,
      } as ModelMessage;
    }

    return {
      role: role as 'user' | 'assistant' | 'system' | 'tool',
      content,
    } as ModelMessage;
  }

  /**
   * 获取当前会话
   */
  getSession(): SessionData | null {
    return this.currentSession;
  }

  /**
   * 获取当前项目
   */
  getProject(): ProjectMetadata | null {
    return this.currentProject;
  }

  /**
   * 保存会话信息
   */
  private async saveSessionInfo(): Promise<void> {
    if (!this.currentSession) return;

    const sessionInfo: SessionInfo = {
      id: this.currentSession.id,
      projectId: this.currentSession.projectId,
      parentId: this.currentSession.parentId,
      agentName: this.currentSession.agentName,
      createdAt: new Date(this.currentSession.createdAt).getTime(),
      updatedAt: Date.now(),
      workdir: this.currentSession.workdir,
      title: this.currentSession.title,
      discoveredTools: this.currentSession.discoveredTools,
      stats: {
        messageCount: this.currentSession.messages.length,
        inputTokens: 0,
        outputTokens: 0,
      },
    };

    await SessionStorage.save(sessionInfo);
  }

  /**
   * 保存当前会话
   */
  async save(): Promise<void> {
    if (!this.currentSession) return;
    await this.saveSessionInfo();
  }

  /**
   * 同步消息到存储（将 AI SDK 消息转换为 Message + Parts）
   */
  async syncMessages(messages: ModelMessage[]): Promise<void> {
    if (!this.currentSession) return;

    const sessionId = this.currentSession.id;

    // 删除旧消息
    await MessageStorage.removeBySession(sessionId);

    // 保存新消息
    for (const message of messages) {
      const messageInfo = await MessageStorage.create(sessionId, message.role as 'user' | 'assistant' | 'system');

      // 将消息内容转换为 Parts
      const partIds: string[] = [];

      if (typeof message.content === 'string') {
        // 简单文本
        const part = await PartStorage.createText(messageInfo.id, message.content);
        partIds.push(part.id);
      } else if (Array.isArray(message.content)) {
        // 复杂内容（多个 parts）
        for (const item of message.content) {
          const itemType = (item as { type: string }).type;
          if (itemType === 'text') {
            const part = await PartStorage.createText(messageInfo.id, (item as { text: string }).text);
            partIds.push(part.id);
          } else if (itemType === 'tool-call') {
            const toolCall = item as unknown as { toolCallId: string; toolName: string; args: Record<string, unknown> };
            const part = await PartStorage.createTool(
              messageInfo.id,
              toolCall.toolCallId,
              toolCall.toolName,
              toolCall.args
            );
            partIds.push(part.id);
          } else if (itemType === 'tool-result') {
            const toolResult = item as unknown as { toolCallId: string; toolName: string; result: unknown };
            const part = await PartStorage.create(messageInfo.id, 'tool', {
              toolCallId: toolResult.toolCallId,
              toolName: toolResult.toolName,
              args: {},
              status: 'completed',
              result: toolResult.result,
            });
            partIds.push(part.id);
          } else if (itemType === 'image') {
            const img = item as unknown as { image: string; mimeType: string };
            const part = await PartStorage.create(messageInfo.id, 'file', {
              filename: 'image',
              mimeType: img.mimeType,
              data: typeof img.image === 'string' ? img.image : '',
            });
            partIds.push(part.id);
          }
        }
      }

      // 更新消息的 partIds
      if (partIds.length > 0) {
        await MessageStorage.update(sessionId, messageInfo.id, { partIds });
      }
    }
  }

  /**
   * 批量设置消息（用于同步整个对话历史）
   */
  async setMessages(messages: ModelMessage[]): Promise<void> {
    if (!this.currentSession) return;
    this.currentSession.messages = messages;
    await this.syncMessages(messages);
    await this.saveSessionInfo();
  }

  /**
   * 添加消息
   */
  async addMessage(message: ModelMessage): Promise<void> {
    if (!this.currentSession) return;
    this.currentSession.messages.push(message);
    await this.setMessages(this.currentSession.messages);
  }

  /**
   * 获取对话历史
   */
  getMessages(): ModelMessage[] {
    return this.currentSession?.messages || [];
  }

  /**
   * 设置已发现的工具
   */
  async setDiscoveredTools(tools: string[]): Promise<void> {
    if (!this.currentSession) return;
    this.currentSession.discoveredTools = tools;
    await this.saveSessionInfo();
  }

  /**
   * 获取已发现的工具
   */
  getDiscoveredTools(): string[] {
    return this.currentSession?.discoveredTools || [];
  }

  /**
   * 更新待办事项
   */
  async setTodos(todos: Array<{ content: string; status: 'pending' | 'in_progress' | 'completed' }>): Promise<void> {
    if (!this.currentSession) return;
    const todoList = await TodoStorage.replace(this.currentSession.id, todos);
    this.currentSession.todos = todoList.items;
  }

  /**
   * 获取待办事项
   */
  getTodos(): TodoItem[] {
    return this.currentSession?.todos || [];
  }

  /**
   * 清空当前会话并创建新会话
   */
  async newSession(workdir?: string): Promise<SessionData> {
    if (!this.currentProject) {
      throw new Error('Project not initialized. Call init() first.');
    }

    const newWorkdir = workdir || this.currentSession?.workdir || process.cwd();

    // 如果工作目录变化，需要切换项目
    if (workdir && workdir !== this.currentProject.workdir) {
      this.currentProject = await this.getOrCreateProject(workdir);
    }

    this.currentSession = await this.createNewSession(newWorkdir);
    await this.saveSessionInfo();
    await this.setCurrentSessionPointer(this.currentSession.id);

    return this.currentSession;
  }

  /**
   * 创建子会话（用于 Task 工具）
   */
  createChildSession(parentId: string, agentName: string, title?: string): SessionData {
    if (!this.currentProject) {
      throw new Error('Project not initialized. Call init() first.');
    }

    const workdir = this.currentSession?.workdir || process.cwd();
    return {
      id: generateSessionId(),
      projectId: this.currentProject.id,
      parentId,
      agentName,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
      workdir,
      title: title || `子任务 (@${agentName})`,
      messages: [],
      discoveredTools: [],
      todos: [],
    };
  }

  /**
   * 保存子会话
   */
  async saveChildSession(session: SessionData): Promise<void> {
    const sessionInfo: SessionInfo = {
      id: session.id,
      projectId: session.projectId,
      parentId: session.parentId,
      agentName: session.agentName,
      createdAt: new Date(session.createdAt).getTime(),
      updatedAt: Date.now(),
      workdir: session.workdir,
      title: session.title,
      discoveredTools: session.discoveredTools,
    };
    await SessionStorage.save(sessionInfo);
  }

  /**
   * 获取当前会话 ID
   */
  getSessionId(): string | undefined {
    return this.currentSession?.id;
  }

  /**
   * 恢复指定会话
   */
  async restoreSession(sessionId: string): Promise<SessionData | null> {
    if (!this.currentProject) {
      throw new Error('Project not initialized. Call init() first.');
    }

    const session = await this.loadSession(this.currentProject.id, sessionId);
    if (!session) return null;

    this.currentSession = session;
    await this.setCurrentSessionPointer(sessionId);

    return session;
  }

  /**
   * 列出当前项目的历史会话
   */
  async listSessions(): Promise<SessionSummary[]> {
    if (!this.currentProject) {
      return this.listAllSessions();
    }

    const sessions = await SessionStorage.listByProject(this.currentProject.id);
    return sessions.map((s) => ({
      id: s.id,
      title: s.title || `会话 ${s.id}`,
      workdir: s.workdir,
      messageCount: s.stats?.messageCount || 0,
      createdAt: new Date(s.createdAt).toISOString(),
      updatedAt: new Date(s.updatedAt).toISOString(),
    }));
  }

  /**
   * 列出所有项目的会话
   */
  async listAllSessions(): Promise<SessionSummary[]> {
    const sessions = await SessionStorage.listAll();
    return sessions.map((s) => ({
      id: s.id,
      title: s.title || `会话 ${s.id}`,
      workdir: s.workdir,
      messageCount: s.stats?.messageCount || 0,
      createdAt: new Date(s.createdAt).toISOString(),
      updatedAt: new Date(s.updatedAt).toISOString(),
    }));
  }

  /**
   * 删除历史会话
   */
  async deleteSession(sessionId: string): Promise<boolean> {
    if (!this.currentProject) return false;

    try {
      // 删除会话的消息和 Parts
      const messageInfos = await MessageStorage.listBySession(sessionId);
      for (const msg of messageInfos) {
        await PartStorage.removeByMessage(msg.id);
      }
      await MessageStorage.removeBySession(sessionId);

      // 删除 todos
      await TodoStorage.removeBySession(sessionId);

      // 删除会话信息
      await SessionStorage.remove(this.currentProject.id, sessionId);

      return true;
    } catch {
      return false;
    }
  }

  /**
   * 获取当前会话 ID（从存储）
   */
  private async getCurrentSessionId(): Promise<string | null> {
    try {
      const pointer = await storage.read<{ sessionId: string }>(['current-session']);
      return pointer.sessionId;
    } catch {
      return null;
    }
  }

  /**
   * 设置当前会话指针
   */
  private async setCurrentSessionPointer(sessionId: string): Promise<void> {
    await storage.write(['current-session'], { sessionId });
  }

  /**
   * 启动自动保存（每 30 秒）
   */
  private startAutoSave(): void {
    if (this.autoSaveInterval) return;

    this.autoSaveInterval = setInterval(async () => {
      await this.save();
    }, 30000);
  }

  /**
   * 停止自动保存
   */
  stopAutoSave(): void {
    if (this.autoSaveInterval) {
      clearInterval(this.autoSaveInterval);
      this.autoSaveInterval = null;
    }
  }

  /**
   * 关闭管理器（保存并停止自动保存）
   */
  async close(): Promise<void> {
    this.stopAutoSave();
    await this.save();
  }

  /**
   * 清理旧会话
   */
  async cleanup(keepCount: number = 50): Promise<number> {
    const sessions = await this.listAllSessions();
    if (sessions.length <= keepCount) {
      return 0;
    }

    const toDelete = sessions.slice(keepCount);
    let deletedCount = 0;

    for (const session of toDelete) {
      if (await this.deleteSession(session.id)) {
        deletedCount++;
      }
    }

    return deletedCount;
  }

  /**
   * 获取存储目录
   */
  getStorageDir(): string {
    return this.storageDir || storage.getDefaultStorageDir();
  }
}

// 导出默认实例
export const sessionManager = new SessionManager();
