/**
 * Zustand Store — Agent 状态管理
 *
 * 管理 Agent 的实时状态：当前会话、消息流、流式输出、工具调用状态、Token 统计。
 */

import { create } from 'zustand';
import { useSessionStore } from './session-store';

// ===== 消息类型 =====

export type MessageRole = 'user' | 'assistant' | 'system' | 'tool';

export interface ToolCallInfo {
  id: string;
  name: string;
  args: Record<string, unknown>;
  status: 'pending' | 'executing' | 'success' | 'error' | 'blocked';
  result?: unknown;
  durationMs?: number;
  error?: string;
}

export interface AttachmentInfo {
  id: string;
  name: string;
  type: 'image' | 'text' | 'other';
  size: number;
  preview?: string;      // 图片 base64 data URL
  textContent?: string;  // 文本文件内容
}

export interface ChatMessage {
  id: string;
  role: MessageRole;
  content: string;
  timestamp: number;
  iteration?: number;
  toolCalls?: ToolCallInfo[];
  reasoningContent?: string;
  attachments?: AttachmentInfo[];
}

// ===== Agent 状态 =====

export type AgentStatus = 'idle' | 'thinking' | 'executing' | 'error';

// ===== Token 统计 =====

export interface TokenUsage {
  inputTokens: number;
  outputTokens: number;
  totalTokens: number;
}

// ===== Trace 步骤 =====

export interface TraceStep {
  iteration: number;
  state: string;
  startedAt: number;
  completedAt?: number;
  thought?: string;
  toolCalls?: ToolCallInfo[];
  tokenUsage?: { promptTokens: number; completionTokens: number; totalTokens: number };
}

// ===== Store 状态 =====

interface AgentState {
  // 会话
  currentSessionId: string | null;
  messages: ChatMessage[];
  agentStatus: AgentStatus;
  currentIteration: number;
  maxIterations: number;

  // Token 统计
  tokenUsage: TokenUsage;

  // Trace
  traceSteps: TraceStep[];

  // 流式
  isStreaming: boolean;
  streamingContent: string;

  // Provider
  provider: string;
  model: string;

  // Actions
  setCurrentSession: (id: string | null) => void;
  setMessages: (messages: ChatMessage[]) => void;
  addMessage: (message: ChatMessage) => void;
  updateMessage: (id: string, updates: Partial<ChatMessage>) => void;
  sendMessage: (content: string, images?: Array<{ url: string; detail?: 'low' | 'high' | 'auto' }>, attachments?: AttachmentInfo[]) => void;
  updateLastAssistantMessage: (delta: string) => void;
  setAgentStatus: (status: AgentStatus) => void;
  setStreaming: (streaming: boolean) => void;
  appendStreamingContent: (delta: string) => void;
  clearStreamingContent: () => void;
  addTraceStep: (step: TraceStep) => void;
  updateTraceStep: (iteration: number, updates: Partial<TraceStep>) => void;
  updateTokenUsage: (usage: Partial<TokenUsage>) => void;
  setProvider: (provider: string, model: string) => void;
  setMaxIterations: (max: number) => void;
  setCurrentIteration: (n: number) => void;
  saveTraceData: () => void;
  clearMessages: () => void;
  abort: () => void;
}

export const useAgentStore = create<AgentState>((set, get) => ({
  // ===== 初始状态 =====
  currentSessionId: null,
  messages: [],
  agentStatus: 'idle',
  currentIteration: 0,
  maxIterations: 20,
  tokenUsage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
  traceSteps: [],
  isStreaming: false,
  streamingContent: '',
  provider: '',
  model: '',

  // ===== Actions =====

  setCurrentSession: (id) => {
    set({ currentSessionId: id, messages: [], traceSteps: [], currentIteration: 0, tokenUsage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 } });

    // 从数据库加载该会话的消息
    if (id && window.metona?.sessions?.getMessages) {
      window.metona.sessions.getMessages(id).then((msgs) => {
        const messages = (msgs as Array<{
          id: string; role: string; content: string;
          reasoningContent?: string; toolCalls?: unknown[];
          attachments?: Array<{ id: string; name: string; type: string; size: number; preview?: string; textContent?: string }>;
          timestamp: number;
        }>).map((m) => ({
          id: m.id,
          role: m.role as ChatMessage['role'],
          content: m.content,
          reasoningContent: m.reasoningContent,
          toolCalls: m.toolCalls as ToolCallInfo[] | undefined,
          attachments: m.attachments as AttachmentInfo[] | undefined,
          timestamp: m.timestamp,
        }));
        set({ messages });
      }).catch(() => {});
    }

    // 从数据库加载该会话的 trace 步骤和 token 用量
    if (id && window.metona?.sessions?.getTrace) {
      window.metona.sessions.getTrace(id).then((data) => {
        if (data) {
          if (data.traceSteps) set({ traceSteps: data.traceSteps as TraceStep[] });
          if (data.tokenUsage) set({ tokenUsage: data.tokenUsage as TokenUsage });
        }
      }).catch(() => {});
    }
  },

  setMessages: (messages) => set({ messages }),

  addMessage: (message) =>
    set((s) => ({ messages: [...s.messages, message] })),

  updateMessage: (id, updates) =>
    set((s) => ({
      messages: s.messages.map((m) =>
        m.id === id ? { ...m, ...updates } : m,
      ),
    })),

  sendMessage: async (content: string, images?: Array<{ url: string; detail?: 'low' | 'high' | 'auto' }>, attachments?: AttachmentInfo[]) => {
    let sessionId = get().currentSessionId;

    // 没有当前会话时自动创建
    if (!sessionId && window.metona?.sessions?.create) {
      try {
        const session = await window.metona.sessions.create() as { id: string; title: string; createdAt: number; updatedAt: number; messageCount: number; pinned: boolean; archived: boolean };
        useSessionStore.getState().addSession({
          id: session.id, title: session.title, createdAt: session.createdAt,
          updatedAt: session.updatedAt, messageCount: session.messageCount,
          pinned: session.pinned, archived: session.archived,
        });
        sessionId = session.id;
        set({ currentSessionId: sessionId });
      } catch {
        // 创建失败时静默
      }
    }

    const userMessage: ChatMessage = {
      id: `msg_${Date.now()}_user`,
      role: 'user',
      content,  // 用户可见内容（纯文本）
      timestamp: Date.now(),
      attachments: attachments && attachments.length > 0 ? attachments : undefined,
    };

    set((s) => ({
      messages: [...s.messages, userMessage],
      agentStatus: 'thinking',
      isStreaming: true,
      streamingContent: '',
      currentIteration: 0,
    }));

    // 自动更新会话标题为用户第一条消息
    if (sessionId && window.metona?.sessions?.getMessages) {
      window.metona.sessions.getMessages(sessionId).then((msgs) => {
        if (msgs.length <= 1) {
          // 这是第一条消息，更新标题
          const title = content.length > 30 ? content.slice(0, 30) + '...' : content;
          window.metona?.sessions?.rename(sessionId, title);
          useSessionStore.getState().updateSession(sessionId, { title });
        }
      }).catch(() => {});
    }

    if (sessionId && window.metona?.agent?.sendMessage) {
      // 构建发给 LLM 的消息
      // images 参数由 ChatInput 传入（已从附件中提取 base64 data URL）
      let llmContent = content;
      const llmImages: Array<{ url: string; detail?: 'low' | 'high' | 'auto' }> = [
        ...(images ?? []),
      ];

      if (attachments && attachments.length > 0) {
        const parts: string[] = [];
        for (const att of attachments) {
          if (att.type === 'image') {
            // 图片已在 images 参数中处理，跳过
            continue;
          }
          // 非图片文件：JSON 格式，Base64 编码内容
          const ext = att.name.split('.').pop() ?? 'unknown';
          let base64Content = '';
          if (att.textContent) {
            base64Content = btoa(unescape(encodeURIComponent(att.textContent)));
          } else if (att.preview) {
            base64Content = att.preview.split(',')[1] ?? '';
          }
          parts.push(JSON.stringify({
            file_name: att.name,
            file_type: ext,
            context_encode: 'Base64',
            context: base64Content,
          }));
        }
        llmContent = parts.length > 0
          ? parts.join('\n') + (content ? '\n\n' + content : '')
          : content;
      }

      const messageWithImages = {
        ...userMessage,
        content: llmContent,
        images: llmImages.length > 0 ? llmImages : undefined,
      };
      window.metona.agent.sendMessage(messageWithImages, sessionId).catch(() => {});
    }
  },

  updateLastAssistantMessage: (delta: string) => {
    set((s) => {
      const messages = [...s.messages];
      const lastMsg = messages[messages.length - 1];
      if (lastMsg?.role === 'assistant') {
        lastMsg.content += delta;
      } else {
        messages.push({
          id: `msg_${Date.now()}_assistant`,
          role: 'assistant',
          content: delta,
          timestamp: Date.now(),
        });
      }
      return { messages };
    });
  },

  setAgentStatus: (status) => set({ agentStatus: status }),

  setStreaming: (streaming) => set({ isStreaming: streaming }),

  appendStreamingContent: (delta) =>
    set((s) => ({ streamingContent: s.streamingContent + delta })),

  clearStreamingContent: () => set({ streamingContent: '' }),

  addTraceStep: (step) =>
    set((s) => ({ traceSteps: [...s.traceSteps, step] })),

  updateTraceStep: (iteration, updates) =>
    set((s) => ({
      traceSteps: s.traceSteps.map((t) =>
        t.iteration === iteration ? { ...t, ...updates } : t,
      ),
    })),

  updateTokenUsage: (usage) =>
    set((s) => ({ tokenUsage: { ...s.tokenUsage, ...usage } })),

  setProvider: (provider, model) => set({ provider, model }),

  setMaxIterations: (max) => set({ maxIterations: max }),

  setCurrentIteration: (currentIteration) => set({ currentIteration }),

  saveTraceData: () => {
    const { currentSessionId, traceSteps, tokenUsage } = get();
    if (currentSessionId && window.metona?.sessions?.saveTrace) {
      window.metona.sessions.saveTrace(currentSessionId, { traceSteps, tokenUsage }).catch(() => {});
    }
  },

  clearMessages: () =>
    set({
      messages: [],
      agentStatus: 'idle',
      currentIteration: 0,
      tokenUsage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
      traceSteps: [],
      isStreaming: false,
      streamingContent: '',
    }),

  abort: () => {
    const sessionId = get().currentSessionId;
    set({ agentStatus: 'idle', isStreaming: false });
    if (sessionId && window.metona?.agent?.abortSession) {
      window.metona.agent.abortSession(sessionId).catch(() => {});
    }
  },
}));
