// ── Leads: Single Lead ──────────────────────────────────────────────────────
// GET   /api/leads/[id]  — Get a single lead by ID
// PATCH /api/leads/[id]  — Update lead fields (dynamic partial update)
//
// Auth: all authenticated users; scoped to own assignments or admin

import { NextRequest, NextResponse } from "next/server"
import { getSessionUser } from "@/lib/auth"
import { query } from "@/lib/db"
import { avatarSvgUrl } from "@/lib/avatar"

// ── Helpers ──────────────────────────────────────────────────────────────────

/**
 * Maps the DB stage name to the client-facing status string.
 */
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"
  }
}

// ── GET ──────────────────────────────────────────────────────────────────────

export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
  try {
    const user = await getSessionUser()
    if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 })

    const { id } = await params
    const isAdmin = user.role === "admin" || user.role === "super_admin"

    // Fetch lead with stage + user JOINs; enforce ownership scoping
    const result = await query(
      `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 l.id = $1 AND l.deleted_at IS NULL
         AND ($2 = true OR l.assigned_to = $3)`,
      [id, isAdmin, user.id]
    )

    if (result.rows.length === 0) {
      return NextResponse.json({ error: "Lead not found" }, { status: 404 })
    }

    const r = result.rows[0]
    const lead = {
      id: r.id,
      companyName: r.company_name || "",
      contactName: r.contact_name,
      email: r.email || "",
      phone: r.phone || "",
      source: "",
      description: r.notes || "",
      status: stageToStatus(r.stage_name),
      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(lead)
  } catch (error) {
    console.error("Lead detail API error:", error)
    return NextResponse.json({ error: "Failed to load lead" }, { status: 500 })
  }
}

// ── Helpers ──────────────────────────────────────────────────────────────────

/**
 * Maps client-facing status back to the default DB stage name.
 * Used when creating or updating leads via PATCH.
 */
function statusToStageName(status: string): string {
  switch (status) {
    case "open": return "New"
    case "contacted": return "Contacted"
    case "pending": return "Qualified"
    case "closed": return "Closed Won"
    case "ignored": return "Closed Lost"
    default: return "New"
  }
}

// ── PATCH ────────────────────────────────────────────────────────────────────

export async function PATCH(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
  try {
    const user = await getSessionUser()
    if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 })

    const { id } = await params
    const isAdmin = user.role === "admin" || user.role === "super_admin"

    // Verify the user has access to this lead before applying updates
    const accessCheck = await query(
      `SELECT id FROM leads WHERE id = $1 AND deleted_at IS NULL
       AND ($2 = true OR assigned_to = $3)`,
      [id, isAdmin, user.id]
    )
    if (accessCheck.rows.length === 0) {
      return NextResponse.json({ error: "Lead not found" }, { status: 404 })
    }

    const body = await request.json()
    const fields: string[] = []
    const values: any[] = []
    let idx = 1

    // Build dynamic SET clause — only include provided fields
    if (body.companyName !== undefined) { fields.push(`company_name = $${idx++}`); values.push(body.companyName) }
    if (body.contactName !== undefined) { fields.push(`contact_name = $${idx++}`); values.push(body.contactName) }
    if (body.email !== undefined) { fields.push(`email = $${idx++}`); values.push(body.email) }
    if (body.phone !== undefined) { fields.push(`phone = $${idx++}`); values.push(body.phone) }
    if (body.description !== undefined) { fields.push(`notes = $${idx++}`); values.push(body.description) }
    if (body.source !== undefined) { fields.push(`source_id = $${idx++}`); values.push(body.source) }
    if (body.assignedUserId !== undefined) {
      // Only admins can reassign leads
      if (!isAdmin) {
        return NextResponse.json({ error: "Only admins can reassign leads" }, { status: 403 })
      }
      fields.push(`assigned_to = $${idx++}`)
      values.push(body.assignedUserId === "none" ? null : body.assignedUserId)
    }
    if (body.status !== undefined) {
      // Resolve the client status → stage ID via the lookup table
      const stageName = statusToStageName(body.status)
      const stageResult = await query("SELECT id FROM lead_stages WHERE name = $1", [stageName])
      if (stageResult.rows.length > 0) {
        fields.push(`stage_id = $${idx++}`)
        values.push(stageResult.rows[0].id)
      }
    }
    if (body.score !== undefined) {
      const score = Number(body.score)
      if (!isFinite(score) || score < 0 || score > 100) {
        return NextResponse.json({ error: "Score must be a number between 0 and 100" }, { status: 400 })
      }
      fields.push(`score = $${idx++}`)
      values.push(score)
    }

    if (fields.length === 0) {
      return NextResponse.json({ error: "No fields to update" }, { status: 400 })
    }

    // Always bump the updated_at timestamp
    fields.push(`updated_at = NOW()`)
    values.push(id)

    const sql = `UPDATE leads SET ${fields.join(", ")} WHERE id = $${idx} AND deleted_at IS NULL RETURNING id`
    const result = await query(sql, values)

    if (result.rows.length === 0) {
      return NextResponse.json({ error: "Lead not found" }, { status: 404 })
    }

    return NextResponse.json({ success: true, id: result.rows[0].id })
  } catch (error) {
    console.error("Lead PATCH error:", error)
    return NextResponse.json({ error: "Failed to update lead" }, { status: 500 })
  }
}
