import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import type { ICommandRecord } from '@/api/terminal'

export const useTerminalStore = defineStore('terminal', () => {
  // --- State ---
  const sessionId = ref<string | null>(null)
  const cwd = ref<string>('~')
  const output = ref<string[]>([])
  const history = ref<ICommandRecord[]>([])
  const isExecuting = ref(false)
  const isWsConnected = ref(false)
  const ws = ref<WebSocket | null>(null)
  const error = ref<string | null>(null)

  // --- Getters ---
  const recentCommands = computed(() => {
    return history.value.slice(-50)
  })

  // --- Actions ---
  function setSessionId(id: string): void {
    sessionId.value = id
  }

  function setCwd(dir: string): void {
    cwd.value = dir
  }

  function appendOutput(text: string): void {
    output.value.push(text)
    // Keep output buffer manageable
    if (output.value.length > 5000) {
      output.value = output.value.slice(-3000)
    }
  }

  function clearOutput(): void {
    output.value = []
  }

  function addHistory(record: ICommandRecord): void {
    history.value.push(record)
    if (history.value.length > 1000) {
      history.value = history.value.slice(-500)
    }
  }

  function clearHistory(): void {
    history.value = []
  }

  function connectWebSocket(): void {
    if (ws.value && ws.value.readyState === WebSocket.OPEN) {
      return
    }

    const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
    const host = window.location.host
    let url = `${protocol}//${host}/api/v1/terminal/ws`
    if (sessionId.value) {
      url += `?session_id=${sessionId.value}`
    }

    const socket = new WebSocket(url)

    socket.onopen = () => {
      isWsConnected.value = true
      appendOutput('\x1b[32m已连接到终端服务\x1b[0m')
    }

    socket.onmessage = (event: MessageEvent) => {
      try {
        const data = JSON.parse(event.data as string)
        handleWsMessage(data)
      } catch {
        // Plain text output
        appendOutput(event.data as string)
      }
    }

    socket.onclose = () => {
      isWsConnected.value = false
      appendOutput('\x1b[33m终端连接已断开\x1b[0m')
      // Auto reconnect after 3 seconds
      setTimeout(() => {
        if (!ws.value || ws.value.readyState === WebSocket.CLOSED) {
          connectWebSocket()
        }
      }, 3000)
    }

    socket.onerror = () => {
      isWsConnected.value = false
      appendOutput('\x1b[31m连接错误\x1b[0m')
    }

    ws.value = socket
  }

  function disconnectWebSocket(): void {
    if (ws.value) {
      ws.value.close()
      ws.value = null
      isWsConnected.value = false
    }
  }

  function sendCommand(command: string): void {
    if (ws.value && ws.value.readyState === WebSocket.OPEN) {
      ws.value.send(JSON.stringify({ type: 'command', command }))
      appendOutput(`\x1b[36m${cwd.value}$\x1b[0m ${command}`)
    }
  }

  function handleWsMessage(data: Record<string, unknown>): void {
    const msgType = data.type as string

    switch (msgType) {
      case 'connected':
        if (data.session_id) {
          sessionId.value = data.session_id as string
        }
        break
      case 'output':
        if (data.output) {
          appendOutput(data.output as string)
        }
        break
      case 'result':
        if (data.output) {
          appendOutput(data.output as string)
        }
        if (data.cwd) {
          cwd.value = data.cwd as string
        }
        if (data.exit_code !== undefined) {
          addHistory({
            command: (data.command as string) || '',
            exit_code: data.exit_code as number,
            output: (data.output as string) || '',
            cwd: cwd.value,
            timestamp: Date.now() / 1000,
            duration_ms: (data.duration_ms as number) || 0,
          })
        }
        isExecuting.value = false
        break
      case 'error':
        appendOutput(`\x1b[31m错误: ${data.message}\x1b[0m`)
        isExecuting.value = false
        break
    }
  }

  return {
    // State
    sessionId,
    cwd,
    output,
    history,
    isExecuting,
    isWsConnected,
    ws,
    error,
    // Getters
    recentCommands,
    // Actions
    setSessionId,
    setCwd,
    appendOutput,
    clearOutput,
    addHistory,
    clearHistory,
    connectWebSocket,
    disconnectWebSocket,
    sendCommand,
  }
})
