import { create } from 'zustand';

export interface FileAttachment {
  id: string;
  originalName: string;
  mimeType: string;
  type: 'image' | 'document' | 'audio' | 'video' | 'other';
  size: number;
  downloadUrl?: string;
  thumbnailUrl?: string;
}

export interface ActiveAgent {
  messageId: string;
  conversationId: string;
  agentType: string;
  agentName: string;
  description: string;
  startedAt: number;
}

export interface CompletedAgent {
  messageId: string;
  conversationId: string;
  agentType: string;
  agentName: string;
  durationMs: number;
  success: boolean;
  completedAt: number;
}

export type CoordinatorPhase = 'analyzing' | 'orchestrating' | 'synthesizing' | null;

export interface Message {
  id: string;
  role: 'user' | 'assistant' | 'system';
  content: string;
  createdAt: string;
  attachments?: FileAttachment[];
  metadata?: Record<string, unknown>;
}

export interface Conversation {
  id: string;
  title: string;
  status: string;
  updatedAt: string;
  messageCount: number;
}

interface ChatState {
  // User
  userId: string | null;
  setUserId: (id: string) => void;

  // Sidebar
  sidebarOpen: boolean;
  setSidebarOpen: (open: boolean) => void;
  toggleSidebar: () => void;

  // Conversations
  conversations: Conversation[];
  currentConversationId: string | null;
  setConversations: (conversations: Conversation[]) => void;
  addConversation: (conversation: Conversation) => void;
  removeConversation: (id: string) => void;
  setCurrentConversation: (id: string | null) => void;
  loadConversations: (userId: string) => Promise<void>;
  deleteConversation: (userId: string, conversationId: string) => Promise<boolean>;

  // Messages
  messages: Record<string, Message[]>;
  addMessage: (conversationId: string, message: Message) => void;
  setMessages: (conversationId: string, messages: Message[]) => void;

  // Streaming
  isStreaming: boolean;
  streamContent: string;
  setStreaming: (isStreaming: boolean) => void;
  appendStreamContent: (content: string) => void;
  clearStreamContent: () => void;

  // WebSocket
  isConnected: boolean;
  setConnected: (connected: boolean) => void;

  // Multi-agent
  activeAgents: ActiveAgent[];
  completedAgents: CompletedAgent[];
  coordinatorPhase: CoordinatorPhase;
  coordinatorMessage: string;
  addActiveAgent: (agent: ActiveAgent) => void;
  completeAgent: (messageId: string, agentType: string, durationMs: number, success: boolean) => void;
  setCoordinatorPhase: (phase: CoordinatorPhase, message: string) => void;
  clearAgentState: () => void;

  // Tool results (collected during streaming, attached to message on stream_end)
  pendingToolResults: Array<{ name: string; result: unknown }>;
  addToolResult: (name: string, result: unknown) => void;
  clearToolResults: () => void;
}

export const useChatStore = create<ChatState>((set, get) => ({
  // User
  userId: null,
  setUserId: (id) => set({ userId: id }),

  // Sidebar - always collapsed by default
  sidebarOpen: false,
  setSidebarOpen: (open) => set({ sidebarOpen: open }),
  toggleSidebar: () => set((state) => ({ sidebarOpen: !state.sidebarOpen })),

  // Conversations
  conversations: [],
  currentConversationId: null,
  setConversations: (conversations) => set({ conversations }),
  addConversation: (conversation) =>
    set((state) => ({
      conversations: [conversation, ...state.conversations],
    })),
  removeConversation: (id) =>
    set((state) => ({
      conversations: state.conversations.filter((c) => c.id !== id),
      currentConversationId:
        state.currentConversationId === id ? null : state.currentConversationId,
    })),
  setCurrentConversation: (id) => set({ currentConversationId: id }),
  loadConversations: async (userId) => {
    try {
      const response = await fetch('/api/v1/conversations', {
        headers: {
          'x-user-id': userId,
        },
      });
      const data = await response.json();
      if (data.success) {
        set({ conversations: data.data });
      }
    } catch (error) {
      console.error('Failed to load conversations:', error);
    }
  },
  deleteConversation: async (userId, conversationId) => {
    try {
      const response = await fetch(`/api/v1/conversations/${conversationId}`, {
        method: 'DELETE',
        headers: {
          'x-user-id': userId,
        },
      });
      const data = await response.json();
      if (data.success) {
        get().removeConversation(conversationId);
        return true;
      }
    } catch (error) {
      console.error('Failed to delete conversation:', error);
    }
    return false;
  },

  // Messages
  messages: {},
  addMessage: (conversationId, message) =>
    set((state) => ({
      messages: {
        ...state.messages,
        [conversationId]: [...(state.messages[conversationId] || []), message],
      },
    })),
  setMessages: (conversationId, messages) =>
    set((state) => ({
      messages: {
        ...state.messages,
        [conversationId]: messages,
      },
    })),

  // Streaming
  isStreaming: false,
  streamContent: '',
  setStreaming: (isStreaming) => set({ isStreaming }),
  appendStreamContent: (content) =>
    set((state) => ({
      streamContent: state.streamContent + content,
    })),
  clearStreamContent: () => set({ streamContent: '' }),

  // WebSocket
  isConnected: false,
  setConnected: (connected) => set({ isConnected: connected }),

  // Multi-agent
  activeAgents: [],
  completedAgents: [],
  coordinatorPhase: null,
  coordinatorMessage: '',
  addActiveAgent: (agent) =>
    set((state) => ({
      activeAgents: [...state.activeAgents, agent],
    })),
  completeAgent: (messageId, agentType, durationMs, success) =>
    set((state) => {
      const agent = state.activeAgents.find(
        (a) => a.messageId === messageId && a.agentType === agentType,
      );
      return {
        activeAgents: state.activeAgents.filter(
          (a) => !(a.messageId === messageId && a.agentType === agentType),
        ),
        completedAgents: agent
          ? [
              ...state.completedAgents,
              {
                messageId: agent.messageId,
                conversationId: agent.conversationId,
                agentType: agent.agentType,
                agentName: agent.agentName,
                durationMs,
                success,
                completedAt: Date.now(),
              },
            ]
          : state.completedAgents,
      };
    }),
  setCoordinatorPhase: (phase, message) =>
    set({ coordinatorPhase: phase, coordinatorMessage: message }),
  clearAgentState: () =>
    set({
      activeAgents: [],
      completedAgents: [],
      coordinatorPhase: null,
      coordinatorMessage: '',
    }),

  // Tool results
  pendingToolResults: [],
  addToolResult: (name, result) =>
    set((state) => ({
      pendingToolResults: [...state.pendingToolResults, { name, result }],
    })),
  clearToolResults: () => set({ pendingToolResults: [] }),
}));
