import { NextRequest, NextResponse } from 'next/server' import { prisma } from '@/lib/db' export const runtime = 'nodejs' export async function GET(request: NextRequest) { try { const { searchParams } = new URL(request.url) const query = searchParams.get('q') const testament = searchParams.get('testament') || 'all' const exactMatch = searchParams.get('exactMatch') === 'true' const books = searchParams.get('books')?.split(',').filter(Boolean) || [] const bookKeys = searchParams.get('bookKeys')?.split(',').filter(Boolean) || [] const locale = (searchParams.get('locale') || 'ro').toLowerCase() const versionAbbr = searchParams.get('version') || undefined if (!query) { return NextResponse.json( { success: false, error: 'Query parameter is required', results: [] }, { status: 400 } ) } // Resolve Bible version to constrain search to selected language/version let bibleVersion: any if (versionAbbr) { bibleVersion = await prisma.bibleVersion.findFirst({ where: { abbreviation: versionAbbr, language: { in: [locale, locale.toLowerCase(), locale.toUpperCase()] } } }) } else { bibleVersion = await prisma.bibleVersion.findFirst({ where: { language: { in: [locale, locale.toLowerCase(), locale.toUpperCase()] }, isDefault: true } }) if (!bibleVersion) { bibleVersion = await prisma.bibleVersion.findFirst({ where: { language: { in: [locale, locale.toLowerCase(), locale.toUpperCase()] } }, orderBy: { createdAt: 'asc' } }) } } if (!bibleVersion) { return NextResponse.json({ success: true, results: [], total: 0 }) } // Build search conditions const searchConditions: any = {} // Text search conditions if (exactMatch) { searchConditions.text = { contains: query, mode: 'insensitive' } } else { // Use ilike for partial matching searchConditions.text = { contains: query, mode: 'insensitive' } } // Testament filter (by orderNum threshold) let testamentFilter: any = {} if (testament === 'old') { testamentFilter = { chapter: { book: { versionId: bibleVersion.id, orderNum: { lte: 39 } } } } } else if (testament === 'new') { testamentFilter = { chapter: { book: { versionId: bibleVersion.id, orderNum: { gt: 39 } } } } } // Books filter let booksFilter: any = {} if (bookKeys.length > 0) { booksFilter = { chapter: { book: { versionId: bibleVersion.id, bookKey: { in: bookKeys } } } } } else if (books.length > 0) { booksFilter = { chapter: { book: { versionId: bibleVersion.id, name: { in: books } } } } } // Combine all filters const baseVersionScope = { chapter: { book: { versionId: bibleVersion.id } } } const whereCondition = { ...searchConditions, ...baseVersionScope, ...testamentFilter, ...booksFilter, } // Search verses const verses = await prisma.bibleVerse.findMany({ where: whereCondition, include: { chapter: { include: { book: true } } }, take: 50, // Limit results orderBy: [ { chapter: { book: { orderNum: 'asc' } } }, { chapter: { chapterNum: 'asc' } }, { verseNum: 'asc' } ] }) // Transform results to match expected format const results = verses.map(verse => { // Calculate relevance based on how well the search term matches const lowerText = verse.text.toLowerCase() const lowerQuery = query.toLowerCase() let relevance = 0.5 // Base relevance if (exactMatch && lowerText.includes(lowerQuery)) { relevance = 0.95 } else if (lowerText.includes(lowerQuery)) { relevance = 0.8 } else { // Check for word matches const queryWords = lowerQuery.split(/\s+/) const textWords = lowerText.split(/\s+/) const matchingWords = queryWords.filter(word => textWords.some(textWord => textWord.includes(word)) ) relevance = 0.3 + (matchingWords.length / queryWords.length) * 0.4 } return { id: verse.id.toString(), book: verse.chapter.book.name, chapter: verse.chapter.chapterNum, verse: verse.verseNum, text: verse.text, relevance: Math.min(relevance, 1.0) // Cap at 1.0 } }) return NextResponse.json({ success: true, results, total: results.length, query, filters: { testament, exactMatch, books } }) } catch (error) { console.error('Error searching verses:', error) return NextResponse.json( { success: false, error: 'Failed to search verses', results: [] }, { status: 500 } ) } }