// src/app/(frontend)/api/search/route.ts
// Main search API endpoint

import { NextRequest, NextResponse } from 'next/server'
import { getPayload } from 'payload'
import config from '@payload-config'
import { searchPosts } from '@/lib/search'
import {
  searchLimiter,
  rateLimitHeaders,
  getClientIpFromRequest,
  isIpBlocked,
} from '@/lib/security'

// Validation constants
const MIN_QUERY_LENGTH = 2
const MAX_QUERY_LENGTH = 100
const MAX_LIMIT = 50
const DEFAULT_LIMIT = 10
const SEARCH_RATE_LIMIT = 30

export async function GET(request: NextRequest) {
  try {
    // IP-Blocklist prüfen
    const ip = getClientIpFromRequest(request)
    if (isIpBlocked(ip)) {
      return NextResponse.json(
        { error: 'Access denied' },
        { status: 403 },
      )
    }

    // Rate limiting (zentral)
    const rateLimit = await searchLimiter.check(ip)

    if (!rateLimit.allowed) {
      return NextResponse.json(
        { error: 'Too many requests. Please try again later.' },
        {
          status: 429,
          headers: rateLimitHeaders(rateLimit, SEARCH_RATE_LIMIT),
        },
      )
    }

    // Parse query parameters
    const { searchParams } = new URL(request.url)
    const query = searchParams.get('q')?.trim() || ''
    const category = searchParams.get('category')?.trim()
    const type = searchParams.get('type')?.trim() as 'blog' | 'news' | 'press' | 'announcement' | undefined
    const tenantParam = searchParams.get('tenant')
    const limitParam = searchParams.get('limit')
    const offsetParam = searchParams.get('offset')
    const localeParam = searchParams.get('locale')?.trim()

    // Validate locale
    const validLocales = ['de', 'en']
    const locale = localeParam && validLocales.includes(localeParam) ? localeParam : 'de'

    // Validate query
    if (query && query.length < MIN_QUERY_LENGTH) {
      return NextResponse.json(
        { error: `Query must be at least ${MIN_QUERY_LENGTH} characters` },
        { status: 400 }
      )
    }

    if (query && query.length > MAX_QUERY_LENGTH) {
      return NextResponse.json(
        { error: `Query must be at most ${MAX_QUERY_LENGTH} characters` },
        { status: 400 }
      )
    }

    // Validate type
    const validTypes = ['blog', 'news', 'press', 'announcement']
    if (type && !validTypes.includes(type)) {
      return NextResponse.json(
        { error: `Invalid type. Must be one of: ${validTypes.join(', ')}` },
        { status: 400 }
      )
    }

    // Parse numeric parameters
    const limit = Math.min(
      Math.max(1, parseInt(limitParam || String(DEFAULT_LIMIT), 10) || DEFAULT_LIMIT),
      MAX_LIMIT
    )
    const offset = Math.max(0, parseInt(offsetParam || '0', 10) || 0)
    const tenantId = tenantParam ? parseInt(tenantParam, 10) : undefined

    // Validate tenant ID if provided
    if (tenantParam && (isNaN(tenantId!) || tenantId! < 1)) {
      return NextResponse.json(
        { error: 'Invalid tenant ID' },
        { status: 400 }
      )
    }

    // Get payload instance
    const payload = await getPayload({ config })

    // Execute search
    const result = await searchPosts(payload, {
      query,
      tenantId,
      categorySlug: category,
      type,
      locale,
      limit,
      offset,
    })

    return NextResponse.json(result, {
      headers: {
        ...rateLimitHeaders(rateLimit, SEARCH_RATE_LIMIT),
        'Cache-Control': 'public, max-age=60, s-maxage=60',
      },
    })
  } catch (error) {
    console.error('[Search API] Error:', error)
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 }
    )
  }
}
