import { NextRequest, NextResponse } from "next/server";
import { z } from "zod";
import DOMPurify from "isomorphic-dompurify";
import validator from "validator";
import { logger } from "@/lib/logger";
import { getClientIp } from "@/lib/utils/ip-extraction";
import { v4 as uuidv4 } from "uuid";
import { createId } from "@paralleldrive/cuid2";
import { prisma } from "@/lib/db";
import { contactSubmissionsAdapter } from "@/lib/adapters/contacts";
import { withSecureRoute } from "@/lib/api-security";
import { rateLimiters } from "@/lib/rate-limiter";
import * as LeadCRM from "@/lib/services/lead-crm.service";
import { getDataSource } from "@/lib/data-source";

// Validation schema for lead capture
const leadSchema = z.object({
  name: z.string().min(2, "Name must be at least 2 characters").max(100),
  email: z.string().email("Invalid email address"),
  phone: z.string().max(20).optional(),
  company: z.string().max(200).optional(),
  resourceTitle: z.string().min(1).max(500),
  resourceType: z
    .enum(["guide", "case-study", "whitepaper", "template", "roi-report"])
    .default("guide"),
  language: z.enum(["ar", "en"]).default("en"),
  recaptchaToken: z.string().optional(),
  metadata: z.record(z.unknown()).optional(),
});

/**
 * Verify reCAPTCHA token with Google
 */
async function verifyRecaptcha(
  token: string,
): Promise<{ success: boolean; score: number }> {
  const secretKey = process.env.RECAPTCHA_SECRET_KEY;
  const threshold = parseFloat(process.env.RECAPTCHA_SCORE_THRESHOLD || "0.5");
  const isDevelopment = process.env.NODE_ENV !== "production";

  // Development mode bypass
  if (isDevelopment) {
    logger.info("[DEV] reCAPTCHA verification bypassed in development mode");
    return { success: true, score: 1.0 };
  }

  if (!secretKey) {
    logger.error("RECAPTCHA_SECRET_KEY not configured");
    return { success: false, score: 0 };
  }

  if (!token) {
    return { success: false, score: 0 };
  }

  try {
    const response = await fetch(
      "https://www.google.com/recaptcha/api/siteverify",
      {
        method: "POST",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
        body: `secret=${secretKey}&response=${token}`,
      },
    );

    const data = await response.json();

    return {
      success: data.success && data.score >= threshold,
      score: data.score || 0,
    };
  } catch (error) {
    logger.error("reCAPTCHA verification failed", { error });
    return { success: false, score: 0 };
  }
}

/**
 * POST /api/leads/resource-download
 * Capture lead information for resource downloads
 * Uses contact_submissions table with topic='resource_download' for storage
 */
export const POST = withSecureRoute(
  async (request: NextRequest) => {
    try {
      const body = await request.json();
      const ip = getClientIp(request);

      // Validate input
      const validation = leadSchema.safeParse(body);
      if (!validation.success) {
        return NextResponse.json(
          { error: "Invalid input", details: validation.error.errors },
          { status: 400 },
        );
      }

      const {
        name,
        email,
        phone,
        company,
        resourceTitle,
        resourceType,
        language,
        recaptchaToken,
        metadata,
      } = validation.data;

      // Verify reCAPTCHA if token provided
      if (recaptchaToken) {
        const recaptchaResult = await verifyRecaptcha(recaptchaToken);
        if (!recaptchaResult.success) {
          logger.warn("Lead form reCAPTCHA failed", {
            ip,
            score: recaptchaResult.score,
          });
          return NextResponse.json(
            { error: "Bot verification failed. Please try again." },
            { status: 400 },
          );
        }
      }

      // Additional email validation
      if (!validator.isEmail(email)) {
        return NextResponse.json(
          { error: "Invalid email address" },
          { status: 400 },
        );
      }

      // Sanitize inputs
      const sanitizedName = DOMPurify.sanitize(name);
      const sanitizedEmail = validator.normalizeEmail(email) || email;
      const sanitizedCompany = company
        ? DOMPurify.sanitize(company)
        : undefined;
      const sanitizedResourceTitle = DOMPurify.sanitize(resourceTitle);

      // ── Convex data-source branch ────────────────────────────────────
      if (getDataSource("leads") === "convex") {
        try {
          const { convexMutation } = await import("@/lib/convex-client");

          // Create lead in Convex
          const leadId = await convexMutation("leads/mutations:createLead", {
            userId: "system",
            name: sanitizedName,
            email: sanitizedEmail,
            company: sanitizedCompany,
            source: "resource_download",
            interest: `${sanitizedResourceTitle} (${resourceType})`,
            notes: metadata ? JSON.stringify(metadata) : undefined,
          });

          if (leadId) {
            // Record activity (fire-and-forget)
            convexMutation("leads/mutations:addActivity", {
              leadId: String(leadId),
              userId: "system",
              type: "NOTE",
              title: `Downloaded resource: ${sanitizedResourceTitle}`,
              description: `Type: ${resourceType}, Language: ${language}`,
              metadata: { resourceType, language, ip },
            }).catch((err: unknown) => {
              logger.error("[Convex] Failed to add lead activity", {
                error: err,
              });
            });

            logger.info("[Convex] Resource download lead captured", {
              leadId: String(leadId),
              resource: resourceTitle,
              resourceType,
            });

            return NextResponse.json({
              success: true,
              message: "Lead captured successfully",
              leadId: String(leadId),
              isReturning: false,
            });
          }
        } catch (error) {
          console.error("[Convex fallback] leads/resource-download:", error);
          // Fall through to Prisma
        }
      }

      // Check if lead already exists for this resource (using contact_submissions)
      const existingLead = await contactSubmissionsAdapter.findFirst({
        where: {
          email: sanitizedEmail,
          topic: "resource_download",
          message: {
            contains: sanitizedResourceTitle,
          },
        },
      });

      if (existingLead) {
        // Lead already captured for this resource, allow download
        logger.info("Returning lead already captured", {
          email: sanitizedEmail,
          resource: resourceTitle,
        });
        return NextResponse.json({
          success: true,
          message: "Access granted",
          leadId: existingLead.id,
          isReturning: true,
        });
      }

      // Sanitize phone if provided
      const sanitizedPhone = phone ? DOMPurify.sanitize(phone) : "";

      // Save new lead using dual-database approach (stores in contact_submissions)

      logger.info("New resource lead captured", {
        leadId: lead.id,
        resource: resourceTitle,
        resourceType,
      });

      // Also create a CRM lead entry (fire-and-forget)
      LeadCRM.createLead("system", {
        name: sanitizedName,
        email: sanitizedEmail,
        company: sanitizedCompany,
        source: "resource_download",
        sourceChannel: "website",
      }).catch((err: Error) => {
        logger.error("Failed to create CRM lead from resource download", {
          error: err.message,
        });
      });

      // Create staff alert for new lead
      await prisma.staff_alerts.create({
        data: {
          id: createId(),
          type: "NEW_CONTACT", // Use existing alert type
          title: "New Resource Download Lead",
          message: `${sanitizedName} downloaded: ${resourceTitle}`,
          severity: "INFO",
          metadata: {
            leadId: lead.id,
            email: sanitizedEmail,
            name: sanitizedName,
            company: sanitizedCompany,
            resource: resourceTitle,
            resourceType,
          },
        },
      });

      return NextResponse.json({
        success: true,
        message: "Lead captured successfully",
        leadId: lead.id,
        isReturning: false,
      });
    } catch (error) {
      logger.error("Lead capture error:", { error });
      return NextResponse.json(
        { error: "Failed to process request" },
        { status: 500 },
      );
    }
  },
  { rateLimiter: rateLimiters.contact },
);
