import { NextRequest, NextResponse } from 'next/server'
import { requireRole } from '@/lib/auth'
import { getDatabase } from '@/lib/db'
import { heavyLimiter } from '@/lib/rate-limit'

interface SearchResult {
  type: 'task' | 'agent' | 'activity' | 'audit' | 'message' | 'notification' | 'webhook' | 'pipeline'
  id: number
  title: string
  subtitle?: string
  excerpt?: string
  created_at: number
  relevance: number
}

/**
 * GET /api/search?q=<query>&type=<optional type filter>&limit=<optional>
 * Global search across all MC entities.
 */
export async function GET(request: NextRequest) {
  const auth = requireRole(request, 'viewer')
  if ('error' in auth) return NextResponse.json({ error: auth.error }, { status: auth.status })

  const rateCheck = heavyLimiter(request)
  if (rateCheck) return rateCheck

  const { searchParams } = new URL(request.url)
  const query = searchParams.get('q')?.trim()
  const typeFilter = searchParams.get('type')
  const limit = Math.min(parseInt(searchParams.get('limit') || '30'), 100)

  if (!query || query.length < 2) {
    return NextResponse.json({ error: 'Query must be at least 2 characters' }, { status: 400 })
  }

  const db = getDatabase()
  const workspaceId = auth.user.workspace_id ?? 1
  const likeQ = `%${query}%`
  const results: SearchResult[] = []

  // Search tasks
  if (!typeFilter || typeFilter === 'task') {
    try {
      const tasks = db.prepare(`
        SELECT id, title, description, status, assigned_to, created_at
        FROM tasks WHERE workspace_id = ? AND (title LIKE ? OR description LIKE ? OR assigned_to LIKE ?)
        ORDER BY created_at DESC LIMIT ?
      `).all(workspaceId, likeQ, likeQ, likeQ, limit) as any[]
      for (const t of tasks) {
        results.push({
          type: 'task',
          id: t.id,
          title: t.title,
          subtitle: `${t.status} ${t.assigned_to ? `· ${t.assigned_to}` : ''}`,
          excerpt: truncateMatch(t.description, query),
          created_at: t.created_at,
          relevance: t.title.toLowerCase().includes(query.toLowerCase()) ? 2 : 1,
        })
      }
    } catch { /* table might not exist */ }
  }

  // Search agents
  if (!typeFilter || typeFilter === 'agent') {
    try {
      const agents = db.prepare(`
        SELECT id, name, role, status, last_activity, created_at
        FROM agents WHERE workspace_id = ? AND (name LIKE ? OR role LIKE ? OR last_activity LIKE ?)
        ORDER BY created_at DESC LIMIT ?
      `).all(workspaceId, likeQ, likeQ, likeQ, limit) as any[]
      for (const a of agents) {
        results.push({
          type: 'agent',
          id: a.id,
          title: a.name,
          subtitle: `${a.role} · ${a.status}`,
          excerpt: a.last_activity,
          created_at: a.created_at,
          relevance: a.name.toLowerCase().includes(query.toLowerCase()) ? 2 : 1,
        })
      }
    } catch { /* table might not exist */ }
  }

  // Search activities
  if (!typeFilter || typeFilter === 'activity') {
    try {
      const activities = db.prepare(`
        SELECT id, type, actor, description, created_at
        FROM activities WHERE workspace_id = ? AND (description LIKE ? OR actor LIKE ?)
        ORDER BY created_at DESC LIMIT ?
      `).all(workspaceId, likeQ, likeQ, limit) as any[]
      for (const a of activities) {
        results.push({
          type: 'activity',
          id: a.id,
          title: a.description,
          subtitle: `by ${a.actor}`,
          created_at: a.created_at,
          relevance: 1,
        })
      }
    } catch { /* table might not exist */ }
  }

  // Search audit log (admin-only — audit_log is instance-global)
  if ((!typeFilter || typeFilter === 'audit') && auth.user.role === 'admin') {
    try {
      const audits = db.prepare(`
        SELECT id, action, actor, detail, created_at
        FROM audit_log WHERE action LIKE ? OR actor LIKE ? OR detail LIKE ?
        ORDER BY created_at DESC LIMIT ?
      `).all(likeQ, likeQ, likeQ, limit) as any[]
      for (const a of audits) {
        results.push({
          type: 'audit',
          id: a.id,
          title: a.action,
          subtitle: `by ${a.actor}`,
          excerpt: truncateMatch(a.detail, query),
          created_at: a.created_at,
          relevance: 1,
        })
      }
    } catch { /* table might not exist */ }
  }

  // Search messages
  if (!typeFilter || typeFilter === 'message') {
    try {
      const messages = db.prepare(`
        SELECT id, from_agent, to_agent, content, conversation_id, created_at
        FROM messages WHERE workspace_id = ? AND (content LIKE ? OR from_agent LIKE ?)
        ORDER BY created_at DESC LIMIT ?
      `).all(workspaceId, likeQ, likeQ, limit) as any[]
      for (const m of messages) {
        results.push({
          type: 'message',
          id: m.id,
          title: `${m.from_agent} → ${m.to_agent || 'all'}`,
          subtitle: m.conversation_id,
          excerpt: truncateMatch(m.content, query),
          created_at: m.created_at,
          relevance: 1,
        })
      }
    } catch { /* table might not exist */ }
  }

  // Search webhooks
  if (!typeFilter || typeFilter === 'webhook') {
    try {
      const webhooks = db.prepare(`
        SELECT id, name, url, events, created_at
        FROM webhooks WHERE workspace_id = ? AND (name LIKE ? OR url LIKE ?)
        ORDER BY created_at DESC LIMIT ?
      `).all(workspaceId, likeQ, likeQ, limit) as any[]
      for (const w of webhooks) {
        results.push({
          type: 'webhook',
          id: w.id,
          title: w.name,
          subtitle: w.url,
          created_at: w.created_at,
          relevance: w.name.toLowerCase().includes(query.toLowerCase()) ? 2 : 1,
        })
      }
    } catch { /* table might not exist */ }
  }

  // Search pipelines
  if (!typeFilter || typeFilter === 'pipeline') {
    try {
      const pipelines = db.prepare(`
        SELECT id, name, description, created_at
        FROM workflow_pipelines WHERE workspace_id = ? AND (name LIKE ? OR description LIKE ?)
        ORDER BY created_at DESC LIMIT ?
      `).all(workspaceId, likeQ, likeQ, limit) as any[]
      for (const p of pipelines) {
        results.push({
          type: 'pipeline',
          id: p.id,
          title: p.name,
          excerpt: truncateMatch(p.description, query),
          created_at: p.created_at,
          relevance: p.name.toLowerCase().includes(query.toLowerCase()) ? 2 : 1,
        })
      }
    } catch { /* table might not exist */ }
  }

  // Sort by relevance then recency
  results.sort((a, b) => b.relevance - a.relevance || b.created_at - a.created_at)

  return NextResponse.json({
    query,
    count: results.length,
    results: results.slice(0, limit),
  })
}

function truncateMatch(text: string | null, query: string, maxLen = 120): string | undefined {
  if (!text) return undefined
  const lower = text.toLowerCase()
  const idx = lower.indexOf(query.toLowerCase())
  if (idx === -1) return text.slice(0, maxLen) + (text.length > maxLen ? '...' : '')
  const start = Math.max(0, idx - 40)
  const end = Math.min(text.length, idx + query.length + 80)
  const excerpt = (start > 0 ? '...' : '') + text.slice(start, end) + (end < text.length ? '...' : '')
  return excerpt
}
