import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
import { apiFetch } from '@/lib/tauri'

export interface HookNotification {
  id: string
  event: string
  icon: string
  title: string
  detail: string
  type: 'info' | 'success' | 'warning' | 'error'
  timestamp: number
  persistent?: boolean
  // Permission-specific
  requestId?: string
  toolName?: string
  toolInput?: unknown
}

export const useClaudeHooksStore = defineStore('claude-hooks', () => {
  const notifications = ref<HookNotification[]>([])
  const MAX_VISIBLE = 5

  const visible = computed(() => notifications.value.slice(-MAX_VISIBLE))

  function add(notif: HookNotification) {
    notifications.value.push(notif)
    if (!notif.persistent) {
      const duration = notif.type === 'warning' ? 5000 : 3500
      setTimeout(() => remove(notif.id), duration)
    }
    // Cap total stored
    if (notifications.value.length > 30) {
      notifications.value = notifications.value.slice(-20)
    }
  }

  function remove(id: string) {
    const idx = notifications.value.findIndex(n => n.id === id)
    if (idx !== -1) notifications.value.splice(idx, 1)
  }

  function clear() {
    notifications.value = []
  }

  // Process a raw claude-hook WS message into a notification (or ignore it)
  function processHook(data: Record<string, any>) {
    const event = data.hook_event_name
    const toolName = data.tool_name || ''
    const id = `hook_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`

    switch (event) {
      case 'SessionStart':
        add({
          id, event, type: 'info',
          icon: '', title: 'Session started',
          detail: data.model ? `Model: ${data.model}` : '',
          timestamp: Date.now()
        })
        break

      case 'UserPromptSubmit': {
        const prompt = data.prompt || ''
        add({
          id, event, type: 'info',
          icon: '', title: 'Prompt',
          detail: prompt.length > 100 ? prompt.slice(0, 100) + '...' : prompt,
          timestamp: Date.now()
        })
        break
      }

      case 'PreToolUse': {
        // Only notify for interesting tools, not reads
        if (/^(Read|Glob|Grep)$/.test(toolName)) return
        const input = data.tool_input || {}
        let detail = ''
        if (toolName === 'Bash') {
          const cmd = input.command || ''
          detail = cmd.length > 80 ? cmd.slice(0, 80) + '...' : cmd
        } else if (toolName === 'Edit' || toolName === 'Write') {
          detail = input.file_path ? shortPath(input.file_path) : ''
        } else if (toolName === 'Task') {
          detail = input.description || input.prompt?.slice(0, 60) || ''
        } else if (toolName === 'WebSearch') {
          detail = input.query || ''
        } else if (toolName === 'WebFetch') {
          detail = input.url || ''
        } else {
          detail = toolName
        }
        add({
          id, event, type: 'info',
          icon: '', title: formatToolName(toolName),
          detail, timestamp: Date.now()
        })
        break
      }

      case 'PostToolUse': {
        // Skip noisy read tools
        if (/^(Read|Glob|Grep)$/.test(toolName)) return
        const response = data.tool_response
        let detail = ''
        if (typeof response === 'string') {
          detail = response.length > 120 ? response.slice(0, 120) + '...' : response
        } else if (response) {
          const json = JSON.stringify(response)
          detail = json.length > 120 ? json.slice(0, 120) + '...' : json
        }
        // Clean control chars and excessive whitespace
        detail = detail.replace(/[\x00-\x1f]+/g, ' ').replace(/\s+/g, ' ').trim()
        if (!detail) return
        add({
          id, event, type: 'success',
          icon: '', title: `${toolName} result`,
          detail, timestamp: Date.now()
        })
        break
      }

      case 'Notification':
        add({
          id, event, type: 'warning',
          icon: '', title: 'Claude notification',
          detail: data.message || '',
          timestamp: Date.now()
        })
        break

      case 'Stop': {
        const response = data.assistant_response || ''
        const detail = response.length > 200 ? response.slice(0, 200) + '...' : response
        add({
          id, event, type: 'success',
          icon: '', title: response ? 'Claude response' : 'Session finished',
          detail,
          timestamp: Date.now(),
          persistent: !!response // Keep visible if there's a response to read
        })
        break
      }
    }
  }

  // Process a claude-permission WS message
  function processPermission(data: Record<string, any>) {
    const id = `perm_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`
    const toolName = data.tool_name || 'Unknown'
    const input = data.tool_input || {}
    let detail = ''
    if (toolName === 'Bash') {
      const cmd = input.command || ''
      detail = cmd.length > 120 ? cmd.slice(0, 120) + '...' : cmd
    } else if (toolName === 'Edit' || toolName === 'Write') {
      detail = input.file_path ? shortPath(input.file_path) : ''
    } else {
      detail = JSON.stringify(input).slice(0, 100)
    }

    add({
      id, event: 'PermissionRequest', type: 'error',
      icon: '', title: `Permission: ${toolName}`,
      detail,
      timestamp: Date.now(),
      persistent: true,
      requestId: data.requestId,
      toolName,
      toolInput: input
    })
  }

  async function respondPermission(notifId: string, requestId: string, decision: 'allow' | 'deny') {
    try {
      await apiFetch('/api/claude-permission-respond', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ requestId, decision })
      })
    } catch (e) {
      console.error('[Hooks] Failed to respond permission:', e)
    }
    remove(notifId)
  }

  return { notifications, visible, add, remove, clear, processHook, processPermission, respondPermission }
})

function shortPath(p: string): string {
  const parts = p.replace(/\\/g, '/').split('/')
  if (parts.length <= 3) return parts.join('/')
  return '.../' + parts.slice(-2).join('/')
}

function formatToolName(name: string): string {
  switch (name) {
    case 'Bash': return 'Running command'
    case 'Edit': return 'Editing file'
    case 'Write': return 'Writing file'
    case 'Task': return 'Spawning agent'
    case 'WebSearch': return 'Searching web'
    case 'WebFetch': return 'Fetching URL'
    case 'NotebookEdit': return 'Editing notebook'
    default: return `Tool: ${name}`
  }
}
