/**
 * Agent Store - OpenClaw 狀態管理 (企業級強化版)
 * ADR-004: Zustand 狀態管理
 *
 * 封裝內容:
 * - Agent 狀態 (idle/thinking/executing/waiting_approval)
 * - 思考串流 (thinkingStream)
 * - SSE 連線邏輯 (含 AbortController + Buffer)
 * - 錯誤處理
 */

import { create } from 'zustand'
import { subscribeWithSelector } from 'zustand/middleware'

// ==================== Types ====================

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

export interface ThinkingStep {
  type: 'thinking' | 'result' | 'error' | 'graph_rag' | 'finops'
  content: string
  timestamp: Date
  // GraphRAG 結構化資料 (可選)
  graphData?: {
    analysisType: 'blast_radius' | 'root_cause'
    targetService: string
    affectedServices?: string[]
    dependencyChain?: string[]
    probableRootCauses?: string[]
    criticalPath?: string[]
  }
  // FinOps 結構化資料 (可選)
  finopsData?: {
    totalWastedUsd: number
    realizableSavingsUsd: number
    freedResourcesUsd: number
    topActions: Array<{
      action: string
      savings: number
      risk: string
    }>
  }
}

export interface Approval {
  id: string
  type: string
  action: {
    pluginId: string
    operation: string
    parameters: Record<string, unknown>
    riskLevel: 'low' | 'medium' | 'high' | 'critical'
  }
  requestedAt: Date
  expiresAt?: Date
}

interface AgentState {
  // ==================== State ====================
  status: AgentStatus
  currentTask: string | null
  thinkingStream: ThinkingStep[]
  pendingApprovals: Approval[]
  conversationId: string | null
  error: string | null

  // SSE 連線控制 (內部使用)
  _abortController: AbortController | null
  _sseRetryCount: number

  // ==================== Actions ====================
  setStatus: (status: AgentStatus) => void
  setCurrentTask: (task: string | null) => void
  setError: (error: string | null) => void

  // Thinking Stream
  appendThinking: (step: ThinkingStep) => void
  clearThinking: () => void

  // SSE 串流控制
  startThinkingStream: (apiUrl?: string) => Promise<void>
  stopThinkingStream: () => void

  // Approvals
  addApproval: (approval: Approval) => void
  removeApproval: (approvalId: string) => void

  // Conversation
  setConversationId: (id: string | null) => void

  // Reset
  reset: () => void
}

// ==================== Constants ====================

// 統帥鐵律: 禁止任何 Fallback IP
const getApiBaseUrl = (): string => {
  if (typeof window === 'undefined') return ''
  const url = process.env.NEXT_PUBLIC_API_URL
  if (!url) {
    console.error('[AWOOOI ERROR] Missing NEXT_PUBLIC_API_URL')
    return ''
  }
  return `${url}/api/v1`
}

const API_BASE_URL = getApiBaseUrl()

const initialState = {
  status: 'idle' as AgentStatus,
  currentTask: null,
  thinkingStream: [],
  pendingApprovals: [],
  conversationId: null,
  error: null,
  _abortController: null,
  _sseRetryCount: 0,
}

// ==================== Store ====================

export const useAgentStore = create<AgentState>()(
  subscribeWithSelector((set, get) => ({
    ...initialState,

    // ==================== Basic Setters ====================

    setStatus: (status) => set({ status, error: status === 'error' ? get().error : null }),

    setCurrentTask: (task) => set({ currentTask: task }),

    setError: (error) => set({ error, status: error ? 'error' : get().status }),

    // ==================== Thinking Stream ====================

    appendThinking: (step) =>
      set((state) => ({
        thinkingStream: [...state.thinkingStream, step],
      })),

    clearThinking: () => set({ thinkingStream: [] }),

    // ==================== SSE Stream Control ====================

    startThinkingStream: async (apiUrl?: string) => {
      const state = get()

      // 中斷前一次未完成的請求
      state._abortController?.abort()

      const abortController = new AbortController()

      set({
        _abortController: abortController,
        status: 'thinking',
        error: null,
        // 如果是重連，保留原本的 streams，否則清空
        thinkingStream: state._sseRetryCount > 0 ? state.thinkingStream : [],
      })

      try {
        const url = apiUrl || `${API_BASE_URL}/agent/thinking`
        const response = await fetch(url, {
          signal: abortController.signal,
        })

        if (!response.ok) {
          throw new Error(`HTTP ${response.status}: ${response.statusText}`)
        }

        // 連線成功，重置重試計數
        set({ _sseRetryCount: 0 })

        const reader = response.body?.getReader()
        if (!reader) {
          throw new Error('無法建立串流通道')
        }

        const decoder = new TextDecoder()
        let buffer = '' // Buffer 累積，防止 TCP 封包切斷 JSON

        // eslint-disable-next-line no-constant-condition -- SSE 串流讀取迴圈，由 done 控制退出
        while (true) {
          const { done, value } = await reader.read()
          if (done) break

          buffer += decoder.decode(value, { stream: true })

          // SSE 規範: 事件之間以 \n\n 分隔
          const events = buffer.split('\n\n')
          buffer = events.pop() || '' // 保留不完整片段

          for (const event of events) {
            if (event.startsWith('data: ')) {
              const data = event.slice(6).trim()

              // 結束標記
              if (data === '[DONE]') {
                set({ status: 'idle' })
                return
              }

              // 安全解析 JSON
              try {
                const parsed = JSON.parse(data) as { type: string; content: string }
                get().appendThinking({
                  type: parsed.type as ThinkingStep['type'],
                  content: parsed.content,
                  timestamp: new Date(),
                })
              } catch (e) {
                console.warn('JSON 解析錯誤，跳過片段:', data)
              }
            }
          }
        }

        set({ status: 'idle' })
      } catch (err: unknown) {
        if (err instanceof Error && err.name === 'AbortError') {
          console.log('SSE 串流已手動中斷')
          set({ status: 'idle', _sseRetryCount: 0 })
        } else {
          const message = err instanceof Error ? err.message : '未知錯誤'
          
          // L2 網路自癒機制: Exponential Backoff Retry
          const maxRetries = 5
          const currentRetries = state._sseRetryCount
          
          if (currentRetries < maxRetries) {
            const delay = Math.min(1000 * Math.pow(2, currentRetries), 30000)
            console.log(`[AWOOOI L2 Healing] SSE Error: ${message}. Retrying in ${delay}ms (Attempt ${currentRetries + 1}/${maxRetries})...`)
            
            get().appendThinking({
              type: 'error',
              content: `連線中斷: ${message}。將在 ${delay/1000} 秒後自動重連 (嘗試 ${currentRetries + 1}/${maxRetries})...`,
              timestamp: new Date(),
            })
            
            set({ _sseRetryCount: currentRetries + 1 })
            setTimeout(() => get().startThinkingStream(apiUrl), delay)
          } else {
            console.error('[AWOOOI L2 Healing] SSE Max retries reached. Escalating to L3 AIOps.')
            set({
              status: 'error',
              error: `Maximum SSE reconnect attempts reached: ${message}`,
            })
            get().appendThinking({
              type: 'error',
              content: `嚴重錯誤: 無法建立串流連線，已達最大重試次數。`,
              timestamp: new Date(),
            })
          }
        }
      }
    },

    stopThinkingStream: () => {
      const state = get()
      state._abortController?.abort()
      set({
        _abortController: null,
        status: 'idle',
      })
    },

    // ==================== Approvals ====================

    addApproval: (approval) =>
      set((state) => ({
        pendingApprovals: [...state.pendingApprovals, approval],
        status: 'waiting_approval',
      })),

    removeApproval: (approvalId) =>
      set((state) => {
        const pendingApprovals = state.pendingApprovals.filter(
          (a) => a.id !== approvalId
        )
        return {
          pendingApprovals,
          status: pendingApprovals.length === 0 ? 'idle' : 'waiting_approval',
        }
      }),

    // ==================== Conversation ====================

    setConversationId: (id) => set({ conversationId: id }),

    // ==================== Reset ====================

    reset: () => {
      get()._abortController?.abort()
      set(initialState)
    },
  }))
)

// ==================== Selectors (效能優化) ====================

export const selectAgentStatus = (state: AgentState) => state.status
export const selectThinkingStream = (state: AgentState) => state.thinkingStream
export const selectIsThinking = (state: AgentState) => state.status === 'thinking'
export const selectHasError = (state: AgentState) => state.status === 'error'
export const selectError = (state: AgentState) => state.error
