import { ref, computed, watch } from 'vue'
import { useSessionState } from '@/stores/session-state'
import { apiFetch } from '@/lib/tauri'
import type { HooksApprovalPermissionRequest, HooksApprovalPlanRequest } from '@/types/hooks-approval'

export interface ApprovalSessionGroup {
  sessionId: string
  agent: string
  permissions: HooksApprovalPermissionRequest[]
  plans: HooksApprovalPlanRequest[]
}

// Singleton modal visibility (shared across all callers)
const modalVisible = ref(false)

export function useGlobalApproval() {
  const sessionStore = useSessionState()

  // ── Derive pending lists from centralized state ──

  const pendingPermissions = computed<HooksApprovalPermissionRequest[]>(() =>
    sessionStore.allPendingApprovals
      .filter(a => a.type === 'permission')
      .map(a => ({
        requestId: a.requestId,
        tool_name: a.toolName,
        tool_input: a.toolInput,
        agent_name: a.agent,
        session_id: sessionStore.agents[a.agent]?.sessionId || undefined,
        cwd: a.cwd,
        timestamp: a.timestamp
      }))
  )

  const pendingPlans = computed<HooksApprovalPlanRequest[]>(() =>
    sessionStore.allPendingApprovals
      .filter(a => a.type === 'plan')
      .map(a => ({
        requestId: a.requestId,
        session_id: sessionStore.agents[a.agent]?.sessionId || undefined,
        permission_mode: undefined,
        lastAssistantText: (a.lastAssistantText as string) || '',
        timestamp: a.timestamp
      }))
  )

  const totalPending = computed(() => pendingPermissions.value.length + pendingPlans.value.length)

  const groupedBySession = computed<ApprovalSessionGroup[]>(() => {
    const map = new Map<string, ApprovalSessionGroup>()

    for (const p of pendingPermissions.value) {
      const key = p.session_id || 'unknown'
      if (!map.has(key)) {
        map.set(key, { sessionId: key, agent: p.agent_name || 'unknown', permissions: [], plans: [] })
      }
      map.get(key)!.permissions.push(p)
    }

    for (const p of pendingPlans.value) {
      const key = p.session_id || 'unknown'
      if (!map.has(key)) {
        map.set(key, { sessionId: key, agent: 'unknown', permissions: [], plans: [] })
      }
      map.get(key)!.plans.push(p)
    }

    return Array.from(map.values())
  })

  // Auto-show modal when new approvals arrive
  watch(totalPending, (val, oldVal) => {
    if (val > 0 && (oldVal === 0 || oldVal === undefined) && !modalVisible.value) {
      modalVisible.value = true
    }
  })

  // ── Actions (call API, server broadcasts resolution to all clients) ──

  async function respondPermission(requestId: string, decision: string, reason?: string) {
    console.log(`[GlobalApproval] Responding permission ${requestId}: ${decision}${reason ? ' reason=' + reason : ''}`)
    try {
      await apiFetch('/api/hooks-approval/respond', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ requestId, decision, reason })
      })
    } catch (e) {
      console.error('[GlobalApproval] Failed to respond permission:', e)
    }
    // No local removal needed — server broadcasts resolve patch → store updates → computed updates
  }

  async function respondPlan(requestId: string, decision: 'approve' | 'reject' | 'edit', reason?: string) {
    console.log(`[GlobalApproval] Responding plan ${requestId}: ${decision}`)
    try {
      await apiFetch('/api/hooks-approval/respond-plan', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ requestId, decision, reason })
      })
    } catch (e) {
      console.error('[GlobalApproval] Failed to respond plan:', e)
    }
  }

  async function ignoreApproval(requestId: string) {
    console.log(`[GlobalApproval] Ignoring ${requestId} (UI-only removal)`)
    try {
      await apiFetch('/api/hooks-approval/ignore', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ requestId })
      })
    } catch (e) {
      console.error('[GlobalApproval] Failed to ignore approval:', e)
    }
  }

  // ── connect/disconnect/fetchPending kept as no-ops for backward compat ──
  // Session state WS (initialized in App.vue) handles everything now.

  function connect() { /* no-op — session-state-ws handles connection */ }
  function disconnect() { /* no-op */ }
  async function fetchPending() { /* no-op — session state snapshot on WS connect covers this */ }

  return {
    pendingPermissions,
    pendingPlans,
    totalPending,
    groupedBySession,
    modalVisible,
    connect,
    disconnect,
    fetchPending,
    respondPermission,
    respondPlan,
    ignoreApproval
  }
}
