import { defineStore } from 'pinia'
import { ref } from 'vue'
import type { StreamEvent, ChartConfig } from '../types'
import { chatWs } from '../services/websocket'
import { useConversationsStore } from './conversations'

export interface ConfirmationRequest {
  type: 'api' | 'sql'
  description: string
  metadataPreview?: string
  fullPayload?: {
    system_prompt?: string
    user_message?: string
    feedback?: string
    conversation_history?: any[]
  }
  query?: string
  tables?: string[]
  attempt?: number
}

export const useChatStore = defineStore('chat', () => {
  const isStreaming = ref(false)
  const streamingContent = ref('')
  const statusMessage = ref('')
  const currentSql = ref('')
  const currentResultMessageId = ref<string | null>(null)
  const currentChartConfig = ref<ChartConfig | null>(null)

  // Confirmation state
  const pendingConfirmation = ref<ConfirmationRequest | null>(null)

  function init() {
    chatWs.connect()
    chatWs.onEvent(handleEvent)
  }

  function handleEvent(event: StreamEvent) {
    const convStore = useConversationsStore()

    switch (event.type) {
      case 'stream_start':
        isStreaming.value = true
        streamingContent.value = ''
        statusMessage.value = ''
        currentSql.value = ''
        currentResultMessageId.value = null
        currentChartConfig.value = null
        pendingConfirmation.value = null
        if (event.conversation_id && event.conversation_id !== convStore.currentConversationId) {
          convStore.currentConversationId = event.conversation_id
        }
        break

      case 'stream_chunk':
        streamingContent.value += event.content || ''
        break

      case 'status':
        statusMessage.value = event.message || ''
        break

      case 'confirm_api':
        pendingConfirmation.value = {
          type: 'api',
          description: (event as any).description || 'Send request to Claude API?',
          metadataPreview: (event as any).metadata_preview || '',
          fullPayload: (event as any).full_payload || undefined,
        }
        break

      case 'confirm_sql':
        pendingConfirmation.value = {
          type: 'sql',
          description: 'Execute this SQL query on the local database?',
          query: (event as any).query || '',
          tables: (event as any).tables || [],
          attempt: (event as any).attempt || 1,
        }
        break

      case 'sql':
        currentSql.value = event.query || ''
        break

      case 'results':
        currentResultMessageId.value = event.message_id || null
        currentChartConfig.value = event.chart_config || null
        break

      case 'stream_end':
        isStreaming.value = false
        statusMessage.value = ''
        pendingConfirmation.value = null
        if (convStore.currentConversationId) {
          convStore.selectConversation(convStore.currentConversationId)
        }
        break

      case 'error':
        isStreaming.value = false
        streamingContent.value = event.message || 'An error occurred.'
        statusMessage.value = ''
        pendingConfirmation.value = null
        break
    }
  }

  function approveConfirmation() {
    pendingConfirmation.value = null
    chatWs.sendRaw({ type: 'confirm' })
  }

  function rejectConfirmation() {
    pendingConfirmation.value = null
    chatWs.sendRaw({ type: 'reject' })
  }

  function sendQuestion(question: string) {
    const convStore = useConversationsStore()

    convStore.addMessage({
      id: crypto.randomUUID(),
      conversation_id: convStore.currentConversationId || '',
      role: 'user',
      content: question,
      has_results: false,
      created_at: new Date().toISOString(),
    })

    chatWs.send(question, convStore.currentConversationId || undefined)
  }

  return {
    isStreaming, streamingContent, statusMessage,
    currentSql, currentResultMessageId, currentChartConfig,
    pendingConfirmation,
    init, sendQuestion, approveConfirmation, rejectConfirmation,
  }
})
