'use client'

import { create } from 'zustand'
import { subscribeWithSelector } from 'zustand/middleware'
import { MODEL_CATALOG } from '@/lib/models'

export type JsonPrimitive = string | number | boolean | null
export type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue | undefined }
type DashboardLayoutUpdater = string[] | null | ((current: string[] | null) => string[] | null)

// Enhanced types for Mission Control
export interface Session {
  id: string
  key: string
  kind: string
  age: string
  model: string
  tokens: string
  flags: string[]
  active: boolean
  startTime?: number
  lastActivity?: number
  messageCount?: number
  cost?: number
  label?: string
}

export interface LogEntry {
  id: string
  timestamp: number
  level: 'info' | 'warn' | 'error' | 'debug'
  source: string
  session?: string
  message: string
  data?: JsonValue
}

export interface CronJob {
  id?: string
  name: string
  schedule: string
  command: string
  model?: string
  agentId?: string
  timezone?: string
  delivery?: string
  enabled: boolean
  lastRun?: number
  nextRun?: number
  lastStatus?: 'success' | 'error' | 'running'
  lastError?: string
}

export interface SpawnRequest {
  id: string
  task: string
  model: string
  label: string
  timeoutSeconds: number
  status: 'pending' | 'running' | 'completed' | 'failed'
  createdAt: number
  completedAt?: number
  result?: string
  error?: string
}

export interface MemoryFile {
  path: string
  name: string
  type: 'file' | 'directory'
  size?: number
  modified?: number
  children?: MemoryFile[]
}

export interface TokenUsage {
  model: string
  sessionId: string
  date: string
  inputTokens: number
  outputTokens: number
  totalTokens: number
  cost: number
  cacheReadTokens?: number
  cacheWriteTokens?: number
}

export interface ModelConfig {
  alias: string
  name: string
  provider: string
  description: string
  costPer1k: number
}

// Mission Control Phase 2 Types
export interface Task {
  id: number
  title: string
  description?: string
  status: 'inbox' | 'assigned' | 'in_progress' | 'review' | 'quality_review' | 'done'
  priority: 'low' | 'medium' | 'high' | 'critical' | 'urgent'
  project_id?: number
  project_ticket_no?: number
  project_name?: string
  project_prefix?: string
  ticket_ref?: string
  assigned_to?: string
  created_by: string
  created_at: number
  updated_at: number
  due_date?: number
  estimated_hours?: number
  actual_hours?: number
  outcome?: 'success' | 'failed' | 'partial' | 'abandoned'
  error_message?: string
  resolution?: string
  feedback_rating?: number
  feedback_notes?: string
  retry_count?: number
  completed_at?: number
  tags?: string[]
  metadata?: JsonValue
  github_issue_number?: number
  github_repo?: string
  github_synced_at?: number
  github_branch?: string
  github_pr_number?: number
  github_pr_state?: string
}

export interface Agent {
  id: number
  name: string
  role: string
  session_key?: string
  soul_content?: string
  working_memory?: string
  status: 'offline' | 'idle' | 'busy' | 'error'
  last_seen?: number
  last_activity?: string
  created_at: number
  updated_at: number
  config?: JsonValue
  taskStats?: {
    total: number
    assigned: number
    in_progress: number
    quality_review: number
    done: number
    completed: number
  }
}

export interface Activity {
  id: number
  type: string
  entity_type: string
  entity_id: number
  actor: string
  description: string
  data?: JsonValue
  created_at: number
  entity?: {
    type: string
    id?: number
    title?: string
    name?: string
    status?: string
    content_preview?: string
    task_title?: string
  }
}

export interface Notification {
  id: number
  recipient: string
  type: string
  title: string
  message: string
  source_type?: string
  source_id?: number
  read_at?: number
  delivered_at?: number
  created_at: number
  source?: {
    type: string
    id?: number
    title?: string
    name?: string
    status?: string
    content_preview?: string
    task_title?: string
  }
}

export interface Comment {
  id: number
  task_id: number
  author: string
  content: string
  created_at: number
  parent_id?: number
  mentions?: string[]
  replies?: Comment[]
}

export interface ChatAttachment {
  name: string
  type: string
  size: number
  dataUrl: string
}

export interface ChatMessage {
  id: number
  conversation_id: string
  from_agent: string
  to_agent: string | null
  content: string
  message_type: 'text' | 'system' | 'handoff' | 'status' | 'command' | 'tool_call'
  metadata?: JsonValue
  attachments?: ChatAttachment[]
  read_at?: number
  created_at: number
  pendingStatus?: 'sending' | 'sent' | 'failed'
}

export interface Conversation {
  id: string
  name?: string
  kind?: string
  source?: 'chat' | 'session'
  session?: {
    prefKey?: string
    sessionId: string
    sessionKey?: string
    sessionKind: 'claude-code' | 'codex-cli' | 'hermes' | 'gateway'
    agent?: string
    displayName?: string
    colorTag?: string
    model?: string
    tokens?: string
    workingDir?: string | null
    lastUserPrompt?: string | null
    active?: boolean
    age?: string
  }
  participants: string[]
  lastMessage?: ChatMessage
  unreadCount: number
  updatedAt: number
}

export interface StandupReport {
  date: string
  generatedAt: string
  summary: {
    totalAgents: number
    totalCompleted: number
    totalInProgress: number
    totalAssigned: number
    totalReview: number
    totalBlocked: number
    totalActivity: number
    overdue: number
  }
  agentReports: Array<{
    agent: {
      name: string
      role: string
      status: string
      last_seen?: number
      last_activity?: string
    }
    completedToday: Task[]
    inProgress: Task[]
    assigned: Task[]
    review: Task[]
    blocked: Task[]
    activity: {
      actionCount: number
      commentsCount: number
    }
  }>
  teamAccomplishments: Task[]
  teamBlockers: Task[]
  overdueTasks: Task[]
}

export interface CurrentUser {
  id: number
  username: string
  display_name: string
  role: 'admin' | 'operator' | 'viewer'
  workspace_id?: number
  tenant_id?: number
  provider?: 'local' | 'google'
  email?: string | null
  avatar_url?: string | null
}

// Billing/provisioning entity that can own multiple Mission Control workspaces.
export interface Tenant {
  id: number
  slug: string
  display_name: string
  status: string
  linux_user: string
  gateway_port?: number | null
  owner_gateway?: string
}

export interface OsUser {
  username: string
  uid: number
  home_dir: string
  shell: string
  linked_tenant_id: number | null
  has_claude: boolean
  has_codex: boolean
  has_openclaw: boolean
  is_process_owner: boolean
}

export interface Project {
  id: number
  name: string
  slug: string
  description?: string
  ticket_prefix: string
  status: string
  github_repo?: string
  deadline?: number
  color?: string
  task_count?: number
  assigned_agents?: string[]
  github_sync_enabled?: boolean
  github_labels_initialized?: boolean
  github_default_branch?: string
}

export interface ConnectionStatus {
  isConnected: boolean
  url: string
  lastConnected?: Date
  reconnectAttempts: number
  latency?: number
  sseConnected?: boolean
}

export interface ExecApprovalRequest {
  id: string
  sessionId: string
  agentName?: string
  toolName: string
  toolArgs: Record<string, any>
  command?: string
  cwd?: string
  host?: string
  resolvedPath?: string
  risk: 'low' | 'medium' | 'high' | 'critical'
  createdAt: number
  expiresAt?: number
  status: 'pending' | 'approved' | 'denied' | 'expired'
}

interface MissionControlStore {
  // Dashboard Mode (local vs full gateway)
  dashboardMode: 'full' | 'local'
  gatewayAvailable: boolean
  bannerDismissed: boolean
  capabilitiesChecked: boolean
  bootComplete: boolean
  subscription: { type: string; provider?: string; rateLimitTier?: string } | null
  defaultOrgName: string
  setDashboardMode: (mode: 'full' | 'local') => void
  setGatewayAvailable: (available: boolean) => void
  dismissBanner: () => void
  setCapabilitiesChecked: (checked: boolean) => void
  setBootComplete: () => void
  setSubscription: (sub: { type: string; provider?: string; rateLimitTier?: string } | null) => void
  setDefaultOrgName: (name: string) => void

  // Update availability
  updateAvailable: { latestVersion: string; releaseUrl: string; releaseNotes: string } | null
  updateDismissedVersion: string | null
  setUpdateAvailable: (info: { latestVersion: string; releaseUrl: string; releaseNotes: string } | null) => void
  dismissUpdate: (version: string) => void

  // OpenClaw update availability
  openclawUpdate: { installed: string; latest: string; releaseUrl: string; releaseNotes: string; updateCommand: string } | null
  openclawUpdateDismissedVersion: string | null
  setOpenclawUpdate: (info: { installed: string; latest: string; releaseUrl: string; releaseNotes: string; updateCommand: string } | null) => void
  dismissOpenclawUpdate: (version: string) => void

  // WebSocket & Connection
  connection: ConnectionStatus
  lastMessage: unknown
  setConnection: (connection: Partial<ConnectionStatus>) => void
  setLastMessage: (message: unknown) => void

  // Mission Control Phase 2 - Tasks
  tasks: Task[]
  selectedTask: Task | null
  setTasks: (tasks: Task[]) => void
  setSelectedTask: (task: Task | null) => void
  addTask: (task: Task) => void
  updateTask: (taskId: number, updates: Partial<Task>) => void
  deleteTask: (taskId: number) => void

  // Mission Control Phase 2 - Agents
  agents: Agent[]
  selectedAgent: Agent | null
  setAgents: (agents: Agent[]) => void
  setSelectedAgent: (agent: Agent | null) => void
  addAgent: (agent: Agent) => void
  updateAgent: (agentId: number, updates: Partial<Agent>) => void
  deleteAgent: (agentId: number) => void

  // Mission Control Phase 2 - Activities
  activities: Activity[]
  setActivities: (activities: Activity[]) => void
  addActivity: (activity: Activity) => void

  // Mission Control Phase 2 - Notifications
  notifications: Notification[]
  unreadNotificationCount: number
  setNotifications: (notifications: Notification[]) => void
  addNotification: (notification: Notification) => void
  markNotificationRead: (notificationId: number) => void
  markAllNotificationsRead: () => void

  // Mission Control Phase 2 - Comments
  taskComments: Record<number, Comment[]>
  setTaskComments: (taskId: number, comments: Comment[]) => void
  addTaskComment: (taskId: number, comment: Comment) => void

  // Mission Control Phase 2 - Standup
  standupReports: StandupReport[]
  currentStandupReport: StandupReport | null
  setStandupReports: (reports: StandupReport[]) => void
  setCurrentStandupReport: (report: StandupReport | null) => void

  // Sessions
  sessions: Session[]
  selectedSession: string | null
  setSessions: (sessions: Session[]) => void
  setSelectedSession: (sessionId: string | null) => void
  updateSession: (sessionId: string, updates: Partial<Session>) => void

  // Logs
  logs: LogEntry[]
  logFilters: {
    level?: string
    source?: string
    session?: string
    search?: string
  }
  addLog: (log: LogEntry) => void
  setLogFilters: (filters: Partial<{
    level?: string
    source?: string
    session?: string
    search?: string
  }>) => void
  clearLogs: () => void

  // Agent Spawning
  spawnRequests: SpawnRequest[]
  addSpawnRequest: (request: SpawnRequest) => void
  updateSpawnRequest: (id: string, updates: Partial<SpawnRequest>) => void

  // Cron Management
  cronJobs: CronJob[]
  setCronJobs: (jobs: CronJob[]) => void
  updateCronJob: (name: string, updates: Partial<CronJob>) => void

  // Memory Browser
  memoryFiles: MemoryFile[]
  selectedMemoryFile: string | null
  memoryContent: string | null
  memoryFileLinks: { wikiLinks: unknown[]; incoming: string[]; outgoing: string[] } | null
  memoryHealth: unknown | null
  setMemoryFiles: (files: MemoryFile[]) => void
  setSelectedMemoryFile: (path: string | null) => void
  setMemoryContent: (content: string | null) => void
  setMemoryFileLinks: (links: { wikiLinks: unknown[]; incoming: string[]; outgoing: string[] } | null) => void
  setMemoryHealth: (health: unknown | null) => void

  // Token Usage & Cost Tracking
  tokenUsage: TokenUsage[]
  addTokenUsage: (usage: TokenUsage) => void
  getUsageByModel: (timeframe: 'day' | 'week' | 'month') => Record<string, number>
  getTotalCost: (timeframe: 'day' | 'week' | 'month') => number

  // Model Configuration
  availableModels: ModelConfig[]
  setAvailableModels: (models: ModelConfig[]) => void

  // Agent Chat
  chatMessages: ChatMessage[]
  conversations: Conversation[]
  activeConversation: string | null
  chatInput: string
  isSendingMessage: boolean
  chatPanelOpen: boolean
  setChatMessages: (messages: ChatMessage[]) => void
  addChatMessage: (message: ChatMessage) => void
  replacePendingMessage: (tempId: number, message: ChatMessage) => void
  updatePendingMessage: (tempId: number, updates: Partial<ChatMessage>) => void
  removePendingMessage: (tempId: number) => void
  setConversations: (conversations: Conversation[]) => void
  setActiveConversation: (conversationId: string | null) => void
  setChatInput: (input: string) => void
  setIsSendingMessage: (loading: boolean) => void
  setChatPanelOpen: (open: boolean) => void
  markConversationRead: (conversationId: string) => void

  // Auth
  currentUser: CurrentUser | null
  setCurrentUser: (user: CurrentUser | null) => void

  // Tenant / Organization context
  activeTenant: Tenant | null
  tenants: Tenant[]
  osUsers: OsUser[]
  setActiveTenant: (tenant: Tenant | null) => void
  setTenants: (tenants: Tenant[]) => void
  fetchTenants: () => Promise<void>
  fetchOsUsers: () => Promise<void>

  // Project context (scoped within current tenant/workspace)
  activeProject: Project | null
  projects: Project[]
  setActiveProject: (project: Project | null) => void
  setProjects: (projects: Project[]) => void
  fetchProjects: () => Promise<void>

  // Project Manager Modal (global)
  showProjectManagerModal: boolean
  setShowProjectManagerModal: (show: boolean) => void

  // Onboarding
  showOnboarding: boolean
  setShowOnboarding: (show: boolean) => void

  // Exec Approvals
  execApprovals: ExecApprovalRequest[]
  setExecApprovals: (approvals: ExecApprovalRequest[]) => void
  addExecApproval: (approval: ExecApprovalRequest) => void
  updateExecApproval: (id: string, updates: Partial<ExecApprovalRequest>) => void

  // Skills (persisted across tab switches)
  skillsList: { id: string; name: string; source: string; path: string; description?: string; registry_slug?: string | null; security_status?: string | null }[] | null
  skillGroups: { source: string; path: string; skills: { id: string; name: string; source: string; path: string; description?: string; registry_slug?: string | null; security_status?: string | null }[] }[] | null
  skillsTotal: number
  setSkillsData: (skills: { id: string; name: string; source: string; path: string; description?: string; registry_slug?: string | null; security_status?: string | null }[], groups: { source: string; path: string; skills: { id: string; name: string; source: string; path: string; description?: string; registry_slug?: string | null; security_status?: string | null }[] }[], total: number) => void

  // Memory Graph (persisted across tab switches)
  memoryGraphAgents: { name: string; dbSize: number; totalChunks: number; totalFiles: number; files: { path: string; chunks: number; textSize: number }[] }[] | null
  setMemoryGraphAgents: (agents: { name: string; dbSize: number; totalChunks: number; totalFiles: number; files: { path: string; chunks: number; textSize: number }[] }[]) => void

  // Security Posture
  securityPosture?: { score: number; level: string }
  setSecurityPosture: (posture: { score: number; level: string } | undefined) => void

  // Dashboard Layout
  dashboardLayout: string[] | null
  setDashboardLayout: (layout: DashboardLayoutUpdater) => void

  // Interface Mode (essential vs full)
  interfaceMode: 'essential' | 'full'
  setInterfaceMode: (mode: 'essential' | 'full') => void

  // UI State
  activeTab: string
  sidebarExpanded: boolean
  collapsedGroups: string[]
  liveFeedOpen: boolean
  headerDensity: 'focus' | 'compact'
  setActiveTab: (tab: string) => void
  toggleSidebar: () => void
  setSidebarExpanded: (expanded: boolean) => void
  toggleGroup: (groupId: string) => void
  toggleLiveFeed: () => void
  setHeaderDensity: (mode: 'focus' | 'compact') => void
}

export const useMissionControl = create<MissionControlStore>()(
  subscribeWithSelector((set, get) => ({
    // Dashboard Mode
    dashboardMode: 'local' as const,
    gatewayAvailable: false,
    bannerDismissed: false,
    capabilitiesChecked: false,
    bootComplete: false,
    subscription: null,
    defaultOrgName: 'Default',
    setDashboardMode: (mode) => set({ dashboardMode: mode }),
    setGatewayAvailable: (available) => set({ gatewayAvailable: available }),
    dismissBanner: () => set({ bannerDismissed: true }),
    setCapabilitiesChecked: (checked) => set({ capabilitiesChecked: checked }),
    setBootComplete: () => set({ bootComplete: true }),
    setSubscription: (sub) => set({ subscription: sub }),
    setDefaultOrgName: (name) => set({ defaultOrgName: name }),

    // Onboarding
    showOnboarding: false,
    setShowOnboarding: (show) => set({ showOnboarding: show }),

    // Update availability
    updateAvailable: null,
    updateDismissedVersion: (() => {
      if (typeof window === 'undefined') return null
      try { return localStorage.getItem('mc-update-dismissed-version') } catch { return null }
    })(),
    setUpdateAvailable: (info) => set({ updateAvailable: info }),
    dismissUpdate: (version) => {
      try { localStorage.setItem('mc-update-dismissed-version', version) } catch {}
      set({ updateDismissedVersion: version })
    },

    // OpenClaw update availability
    openclawUpdate: null,
    openclawUpdateDismissedVersion: (() => {
      if (typeof window === 'undefined') return null
      try { return localStorage.getItem('mc-openclaw-update-dismissed') } catch { return null }
    })(),
    setOpenclawUpdate: (info) => set({ openclawUpdate: info }),
    dismissOpenclawUpdate: (version) => {
      try { localStorage.setItem('mc-openclaw-update-dismissed', version) } catch {}
      set({ openclawUpdateDismissedVersion: version })
    },

    // Connection state
    connection: {
      isConnected: false,
      url: '',
      reconnectAttempts: 0
    },
    lastMessage: null,
    setConnection: (connection) =>
      set((state) => ({ 
        connection: { ...state.connection, ...connection } 
      })),
    setLastMessage: (message) => set({ lastMessage: message }),

    // Sessions
    sessions: [],
    selectedSession: null,
    setSessions: (sessions) => set({ sessions }),
    setSelectedSession: (sessionId) => set({ selectedSession: sessionId }),
    updateSession: (sessionId, updates) =>
      set((state) => ({
        sessions: state.sessions.map((session) =>
          session.id === sessionId ? { ...session, ...updates } : session
        ),
      })),

    // Logs
    logs: [],
    logFilters: {},
    addLog: (log) =>
      set((state) => {
        // Check if log already exists to prevent duplicates
        const existingLogIndex = state.logs.findIndex(existingLog => existingLog.id === log.id)
        if (existingLogIndex !== -1) {
          // Update existing log
          const updatedLogs = [...state.logs]
          updatedLogs[existingLogIndex] = log
          return { logs: updatedLogs }
        }
        // Add new log at the beginning (newest first)
        return {
          logs: [log, ...state.logs].slice(0, 1000), // Keep last 1000 logs
        }
      }),
    setLogFilters: (filters) =>
      set((state) => ({
        logFilters: { ...state.logFilters, ...filters },
      })),
    clearLogs: () => set({ logs: [] }),

    // Agent Spawning
    spawnRequests: [],
    addSpawnRequest: (request) =>
      set((state) => ({
        spawnRequests: [request, ...state.spawnRequests].slice(0, 500),
      })),
    updateSpawnRequest: (id, updates) =>
      set((state) => ({
        spawnRequests: state.spawnRequests.map((req) =>
          req.id === id ? { ...req, ...updates } : req
        ),
      })),

    // Cron Management
    cronJobs: [],
    setCronJobs: (jobs) => set({ cronJobs: jobs }),
    updateCronJob: (name, updates) =>
      set((state) => ({
        cronJobs: state.cronJobs.map((job) =>
          job.name === name ? { ...job, ...updates } : job
        ),
      })),

    // Memory Browser
    memoryFiles: [],
    selectedMemoryFile: null,
    memoryContent: null,
    memoryFileLinks: null,
    memoryHealth: null,
    setMemoryFiles: (files) => set({ memoryFiles: files }),
    setSelectedMemoryFile: (path) => set({ selectedMemoryFile: path }),
    setMemoryContent: (content) => set({ memoryContent: content }),
    setMemoryFileLinks: (links) => set({ memoryFileLinks: links }),
    setMemoryHealth: (health) => set({ memoryHealth: health }),

    // Token Usage
    tokenUsage: [],
    addTokenUsage: (usage) =>
      set((state) => ({
        tokenUsage: [...state.tokenUsage, usage].slice(-2000),
      })),
    getUsageByModel: (timeframe) => {
      const { tokenUsage } = get()
      const now = new Date()
      let cutoff: Date

      switch (timeframe) {
        case 'day':
          cutoff = new Date(now.getTime() - 24 * 60 * 60 * 1000)
          break
        case 'week':
          cutoff = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000)
          break
        case 'month':
          cutoff = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000)
          break
        default:
          cutoff = new Date(0)
      }

      return tokenUsage
        .filter((usage) => new Date(usage.date) >= cutoff)
        .reduce((acc, usage) => {
          acc[usage.model] = (acc[usage.model] || 0) + usage.totalTokens
          return acc
        }, {} as Record<string, number>)
    },
    getTotalCost: (timeframe) => {
      const { tokenUsage } = get()
      const now = new Date()
      let cutoff: Date

      switch (timeframe) {
        case 'day':
          cutoff = new Date(now.getTime() - 24 * 60 * 60 * 1000)
          break
        case 'week':
          cutoff = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000)
          break
        case 'month':
          cutoff = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000)
          break
        default:
          cutoff = new Date(0)
      }

      return tokenUsage
        .filter((usage) => new Date(usage.date) >= cutoff)
        .reduce((acc, usage) => acc + usage.cost, 0)
    },

    // Model Configuration
    availableModels: [...MODEL_CATALOG],
    setAvailableModels: (models) => set({ availableModels: models }),

    // Auth
    currentUser: null,
    setCurrentUser: (user) => set({ currentUser: user }),

    // Tenant / Organization context
    activeTenant: (() => {
      if (typeof window === 'undefined') return null
      try {
        const raw = localStorage.getItem('mc-active-tenant')
        return raw ? JSON.parse(raw) as Tenant : null
      } catch { return null }
    })(),
    tenants: [],
    osUsers: [],
    setActiveTenant: (tenant) => {
      try {
        if (tenant) {
          localStorage.setItem('mc-active-tenant', JSON.stringify(tenant))
        } else {
          localStorage.removeItem('mc-active-tenant')
        }
      } catch {}
      set({ activeTenant: tenant })
    },
    setTenants: (tenants) => set({ tenants }),
    fetchTenants: async () => {
      try {
        const res = await fetch('/api/super/tenants', { cache: 'no-store' })
        if (!res.ok) return
        const data = await res.json()
        const tenantList = Array.isArray(data?.tenants) ? data.tenants : []
        set({ tenants: tenantList })
      } catch {}
    },
    fetchOsUsers: async () => {
      try {
        const res = await fetch('/api/super/os-users', { cache: 'no-store' })
        if (!res.ok) return
        const data = await res.json()
        set({ osUsers: Array.isArray(data?.users) ? data.users : [] })
      } catch {}
    },

    // Project context
    activeProject: (() => {
      if (typeof window === 'undefined') return null
      try {
        const raw = localStorage.getItem('mc-active-project')
        return raw ? JSON.parse(raw) as Project : null
      } catch { return null }
    })(),
    projects: [],
    setActiveProject: (project) => {
      try {
        if (project) {
          localStorage.setItem('mc-active-project', JSON.stringify(project))
        } else {
          localStorage.removeItem('mc-active-project')
        }
      } catch {}
      set({ activeProject: project })
    },
    setProjects: (projects) => set({ projects }),
    fetchProjects: async () => {
      try {
        const res = await fetch('/api/projects', { cache: 'no-store' })
        if (!res.ok) return
        const data = await res.json()
        const projectList = Array.isArray(data?.projects) ? data.projects : []
        set({ projects: projectList })
      } catch {}
    },

    // Project Manager Modal (global)
    showProjectManagerModal: false,
    setShowProjectManagerModal: (show) => set({ showProjectManagerModal: show }),

    // Exec Approvals
    execApprovals: [],
    setExecApprovals: (approvals) => set({ execApprovals: approvals }),
    addExecApproval: (approval) =>
      set((state) => {
        if (state.execApprovals.some(a => a.id === approval.id)) return state
        return { execApprovals: [approval, ...state.execApprovals].slice(0, 200) }
      }),
    updateExecApproval: (id, updates) =>
      set((state) => ({
        execApprovals: state.execApprovals.map(a => a.id === id ? { ...a, ...updates } : a),
      })),

    // Skills
    skillsList: null,
    skillGroups: null,
    skillsTotal: 0,
    setSkillsData: (skills, groups, total) => set({ skillsList: skills, skillGroups: groups, skillsTotal: total }),

    // Memory Graph
    memoryGraphAgents: null,
    setMemoryGraphAgents: (agents) => set({ memoryGraphAgents: agents }),

    // Security Posture
    securityPosture: undefined,
    setSecurityPosture: (posture) => set({ securityPosture: posture }),

    // Dashboard Layout
    dashboardLayout: (() => {
      if (typeof window === 'undefined') return null
      try {
        const raw = localStorage.getItem('mc-dashboard-layout')
        return raw ? JSON.parse(raw) as string[] : null
      } catch { return null }
    })(),
    setDashboardLayout: (layoutOrUpdater) => {
      const currentLayout = get().dashboardLayout
      const layout = typeof layoutOrUpdater === 'function'
        ? layoutOrUpdater(currentLayout)
        : layoutOrUpdater
      try {
        if (layout) {
          localStorage.setItem('mc-dashboard-layout', JSON.stringify(layout))
        } else {
          localStorage.removeItem('mc-dashboard-layout')
        }
      } catch {}
      set({ dashboardLayout: layout })
    },

    // Interface Mode
    interfaceMode: 'essential' as const,
    setInterfaceMode: (mode) => set({ interfaceMode: mode }),

    // UI State — sidebar & layout persistence
    activeTab: 'overview',
    sidebarExpanded: (() => {
      if (typeof window === 'undefined') return false
      try { return localStorage.getItem('mc-sidebar-expanded') === 'true' } catch { return false }
    })(),
    collapsedGroups: (() => {
      if (typeof window === 'undefined') return [] as string[]
      try {
        const raw = localStorage.getItem('mc-sidebar-groups')
        return raw ? JSON.parse(raw) as string[] : []
      } catch { return [] as string[] }
    })(),
    liveFeedOpen: (() => {
      if (typeof window === 'undefined') return true
      try { return localStorage.getItem('mc-livefeed-open') !== 'false' } catch { return true }
    })(),
    headerDensity: (() => {
      if (typeof window === 'undefined') return 'focus' as const
      try {
        const raw = localStorage.getItem('mc-header-density')
        return raw === 'compact' ? 'compact' : 'focus'
      } catch { return 'focus' as const }
    })(),
    setActiveTab: (tab) => set({ activeTab: tab }),
    toggleSidebar: () =>
      set((state) => {
        const next = !state.sidebarExpanded
        try { localStorage.setItem('mc-sidebar-expanded', String(next)) } catch {}
        return { sidebarExpanded: next }
      }),
    setSidebarExpanded: (expanded) => {
      try { localStorage.setItem('mc-sidebar-expanded', String(expanded)) } catch {}
      set({ sidebarExpanded: expanded })
    },
    toggleGroup: (groupId) =>
      set((state) => {
        const next = state.collapsedGroups.includes(groupId)
          ? state.collapsedGroups.filter(g => g !== groupId)
          : [...state.collapsedGroups, groupId]
        try { localStorage.setItem('mc-sidebar-groups', JSON.stringify(next)) } catch {}
        return { collapsedGroups: next }
      }),
    toggleLiveFeed: () =>
      set((state) => {
        const next = !state.liveFeedOpen
        try { localStorage.setItem('mc-livefeed-open', String(next)) } catch {}
        return { liveFeedOpen: next }
      }),
    setHeaderDensity: (mode) => {
      try { localStorage.setItem('mc-header-density', mode) } catch {}
      set({ headerDensity: mode })
    },

    // Mission Control Phase 2 - Tasks
    tasks: [],
    selectedTask: null,
    setTasks: (tasks) => set({ tasks }),
    setSelectedTask: (task) => set({ selectedTask: task }),
    addTask: (task) =>
      set((state) => ({
        tasks: [task, ...state.tasks]
      })),
    updateTask: (taskId, updates) =>
      set((state) => ({
        tasks: state.tasks.map((task) =>
          task.id === taskId ? { ...task, ...updates } : task
        ),
        selectedTask: state.selectedTask?.id === taskId
          ? { ...state.selectedTask, ...updates }
          : state.selectedTask
      })),
    deleteTask: (taskId) =>
      set((state) => ({
        tasks: state.tasks.filter((task) => task.id !== taskId),
        selectedTask: state.selectedTask?.id === taskId ? null : state.selectedTask
      })),

    // Mission Control Phase 2 - Agents
    agents: [],
    selectedAgent: null,
    setAgents: (agents) => set({ agents }),
    setSelectedAgent: (agent) => set({ selectedAgent: agent }),
    addAgent: (agent) =>
      set((state) => ({
        agents: [agent, ...state.agents]
      })),
    updateAgent: (agentId, updates) =>
      set((state) => ({
        agents: state.agents.map((agent) =>
          agent.id === agentId ? { ...agent, ...updates } : agent
        ),
        selectedAgent: state.selectedAgent?.id === agentId
          ? { ...state.selectedAgent, ...updates }
          : state.selectedAgent
      })),
    deleteAgent: (agentId) =>
      set((state) => ({
        agents: state.agents.filter((agent) => agent.id !== agentId),
        selectedAgent: state.selectedAgent?.id === agentId ? null : state.selectedAgent
      })),

    // Mission Control Phase 2 - Activities
    activities: [],
    setActivities: (activities) => set({ activities }),
    addActivity: (activity) =>
      set((state) => ({
        activities: [activity, ...state.activities].slice(0, 1000) // Keep last 1000
      })),

    // Mission Control Phase 2 - Notifications
    notifications: [],
    unreadNotificationCount: 0,
    setNotifications: (notifications) =>
      set({
        notifications,
        unreadNotificationCount: notifications.filter(n => !n.read_at).length
      }),
    addNotification: (notification) =>
      set((state) => ({
        notifications: [notification, ...state.notifications].slice(0, 500),
        unreadNotificationCount: state.unreadNotificationCount + 1
      })),
    markNotificationRead: (notificationId) =>
      set((state) => ({
        notifications: state.notifications.map((notification) =>
          notification.id === notificationId 
            ? { ...notification, read_at: Math.floor(Date.now() / 1000) }
            : notification
        ),
        unreadNotificationCount: Math.max(0, state.unreadNotificationCount - 1)
      })),
    markAllNotificationsRead: () =>
      set((state) => ({
        notifications: state.notifications.map((notification) =>
          notification.read_at ? notification : { ...notification, read_at: Math.floor(Date.now() / 1000) }
        ),
        unreadNotificationCount: 0
      })),

    // Mission Control Phase 2 - Comments
    taskComments: {},
    setTaskComments: (taskId, comments) =>
      set((state) => ({
        taskComments: { ...state.taskComments, [taskId]: comments }
      })),
    addTaskComment: (taskId, comment) =>
      set((state) => ({
        taskComments: {
          ...state.taskComments,
          [taskId]: [comment, ...(state.taskComments[taskId] || [])]
        }
      })),

    // Agent Chat
    chatMessages: [],
    conversations: [],
    activeConversation: null,
    chatInput: '',
    isSendingMessage: false,
    chatPanelOpen: false,
    setChatMessages: (messages) => set({ chatMessages: messages.slice(-500) }),
    addChatMessage: (message) =>
      set((state) => {
        // Deduplicate: skip if a message with the same server ID already exists
        if (message.id > 0 && state.chatMessages.some(m => m.id === message.id)) {
          return state
        }
        const messages = [...state.chatMessages, message].slice(-500)
        const conversations = state.conversations.map((conv) =>
          conv.id === message.conversation_id
            ? { ...conv, lastMessage: message, updatedAt: message.created_at }
            : conv
        )
        return { chatMessages: messages, conversations }
      }),
    replacePendingMessage: (tempId, message) =>
      set((state) => ({
        chatMessages: state.chatMessages.map(m =>
          m.id === tempId ? { ...message, pendingStatus: 'sent' } : m
        ),
      })),
    updatePendingMessage: (tempId, updates) =>
      set((state) => ({
        chatMessages: state.chatMessages.map(m =>
          m.id === tempId ? { ...m, ...updates } : m
        ),
      })),
    removePendingMessage: (tempId) =>
      set((state) => ({
        chatMessages: state.chatMessages.filter(m => m.id !== tempId),
      })),
    setConversations: (conversations) => set({ conversations }),
    setActiveConversation: (conversationId) => set({ activeConversation: conversationId }),
    setChatInput: (input) => set({ chatInput: input }),
    setIsSendingMessage: (loading) => set({ isSendingMessage: loading }),
    setChatPanelOpen: (open) => set({ chatPanelOpen: open }),
    markConversationRead: (conversationId) =>
      set((state) => ({
        conversations: state.conversations.map((conv) =>
          conv.id === conversationId
            ? { ...conv, unreadCount: 0 }
            : conv
        ),
        chatMessages: state.chatMessages.map((msg) =>
          msg.conversation_id === conversationId && !msg.read_at
            ? { ...msg, read_at: Math.floor(Date.now() / 1000) }
            : msg
        )
      })),

    // Mission Control Phase 2 - Standup
    standupReports: [],
    currentStandupReport: null,
    setStandupReports: (reports) => set({ standupReports: reports }),
    setCurrentStandupReport: (report) => set({ currentStandupReport: report }),
  }))
)
