import { NextRequest, NextResponse } from "next/server" import { getSessionUser } from "@/lib/auth" import { query } from "@/lib/db" import { avatarSvgUrl } from "@/lib/avatar" function stageToStatus(name: string): string { switch (name) { case "New": return "open" case "Contacted": return "contacted" case "Qualified": case "Interested": case "Demo Scheduled": case "Negotiation": return "pending" case "Closed Won": return "closed" case "Closed Lost": return "ignored" default: return "open" } } function getPeriodDateRange(period: string): { start: Date; end: Date } | null { if (period === "all") return null const end = new Date() let start: Date switch (period) { case "7days": start = new Date(end); start.setDate(start.getDate() - 7); break case "30days": start = new Date(end); start.setDate(start.getDate() - 30); break case "12months": start = new Date(end); start.setFullYear(start.getFullYear() - 12); break case "6months": default: start = new Date(end); start.setMonth(start.getMonth() - 6); break } return { start, end } } export async function GET(request: NextRequest) { try { const user = await getSessionUser() if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }) const { searchParams } = new URL(request.url) const search = searchParams.get("search") || "" const status = searchParams.get("status") || "all" const period = searchParams.get("period") || "all" const limit = parseInt(searchParams.get("limit") || "50", 10) const offset = parseInt(searchParams.get("offset") || "0", 10) const isAdmin = user.role === "admin" || user.role === "super_admin" const params: any[] = [] let paramIdx = 1 const conditions: string[] = ["l.deleted_at IS NULL"] if (period !== "all") { const range = getPeriodDateRange(period) if (range) { conditions.push(`l.created_at >= $${paramIdx} AND l.created_at <= $${paramIdx + 1}`) params.push(range.start.toISOString(), range.end.toISOString()) paramIdx += 2 } } if (search) { conditions.push(`(l.contact_name ILIKE $${paramIdx} OR l.company_name ILIKE $${paramIdx} OR l.email ILIKE $${paramIdx} OR l.phone ILIKE $${paramIdx})`) params.push(`%${search}%`) paramIdx++ } if (!isAdmin) { conditions.push(`l.assigned_to = $${paramIdx}`) params.push(user.id) paramIdx++ } // Push status filter into SQL (avoid client-side filtering after pagination) const statusStageMap: Record = { open: ["New"], contacted: ["Contacted"], pending: ["Qualified", "Interested", "Demo Scheduled", "Negotiation"], closed: ["Closed Won"], ignored: ["Closed Lost"], } if (status !== "all") { const stageNames = statusStageMap[status] if (stageNames) { const stagePlaceholders = stageNames.map((_, i) => `$${paramIdx + i}`) conditions.push(`ls.name IN (${stagePlaceholders.join(", ")})`) params.push(...stageNames) paramIdx += stageNames.length } } const whereClause = conditions.join(" AND ") // Total count (same filters, no pagination) const countResult = await query( `SELECT COUNT(*) AS total FROM leads l JOIN lead_stages ls ON ls.id = l.stage_id WHERE ${whereClause}`, params.slice(0, paramIdx - 1), ) const total = parseInt(countResult.rows[0]?.total || "0", 10) // Data query with pagination const dataSql = `SELECT l.id, l.company_name, l.contact_name, l.email, l.phone, l.score, l.assigned_to, l.created_at, l.updated_at, l.notes, l.source_id, ls.name AS stage_name, u.id AS user_id, u.first_name, u.last_name, u.email AS user_email, u.avatar_url FROM leads l JOIN lead_stages ls ON ls.id = l.stage_id LEFT JOIN users u ON u.id = l.assigned_to WHERE ${whereClause} ORDER BY l.created_at DESC LIMIT $${paramIdx} OFFSET $${paramIdx + 1}` const dataParams = [...params, limit, offset] const result = await query(dataSql, dataParams) const leads = result.rows.map((r: any) => { const s = stageToStatus(r.stage_name) return { id: r.id, companyName: r.company_name || "", contactName: r.contact_name, email: r.email || "", phone: r.phone || "", source: "", description: r.notes || "", status: s, assignedUserId: r.assigned_to, assignedUser: r.assigned_to ? { id: r.user_id, name: `${r.first_name} ${r.last_name}`, email: r.user_email, avatar: avatarSvgUrl(`${r.first_name} ${r.last_name}`), } : null, createdAt: r.created_at, updatedAt: r.updated_at, } }) return NextResponse.json({ leads, total }) } catch (error) { console.error("Leads API error:", error) return NextResponse.json({ error: "Failed to load leads" }, { status: 500 }) } } export async function POST(request: NextRequest) { try { const user = await getSessionUser() if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }) const body = await request.json() const isAdmin = user.role === "admin" || user.role === "super_admin" // Non-admin users can only assign leads to themselves; admin/super_admin can assign to anyone let assignedUserId = body.assignedUserId if (!isAdmin) { assignedUserId = user.id } else if (assignedUserId === "none" || !assignedUserId) { assignedUserId = null } const stageResult = await query( "SELECT id FROM lead_stages WHERE name = $1", [body.status === "open" ? "New" : "Contacted"] ) const stageId = stageResult.rows[0]?.id || 1 const result = await query( `INSERT INTO leads (company_name, contact_name, email, phone, notes, source_id, stage_id, assigned_to, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW(), NOW()) RETURNING id`, [ body.companyName, body.contactName, body.email, body.phone || null, body.description || null, body.source || null, stageId, assignedUserId, ] ) return NextResponse.json({ success: true, id: result.rows[0].id }, { status: 201 }) } catch (error) { console.error("Leads POST error:", error) return NextResponse.json({ error: "Failed to create lead" }, { status: 500 }) } } export async function DELETE(request: NextRequest) { try { const user = await getSessionUser() if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }) const isAdmin = user.role === "admin" || user.role === "super_admin" const { searchParams } = new URL(request.url) const id = searchParams.get("id") if (!id) return NextResponse.json({ error: "id is required" }, { status: 400 }) const result = await query( "UPDATE leads SET deleted_at = NOW() WHERE id = $1 AND deleted_at IS NULL AND ($2 = true OR assigned_to = $3) RETURNING id", [id, isAdmin, user.id] ) if (result.rows.length === 0) { return NextResponse.json({ error: "Lead not found" }, { status: 404 }) } return NextResponse.json({ success: true }) } catch (error) { console.error("Leads DELETE error:", error) return NextResponse.json({ error: "Failed to delete lead" }, { status: 500 }) } }