/**
 * Real Estate Client Requirements API
 * GET  - List client requirements with match counts
 * POST - Create new client requirements profile
 */

import { NextRequest } from "next/server";
import { auth } from "@/lib/auth";
import { prisma } from "@/lib/db";
import { getAuthenticatedEmail } from "@/lib/utils/auth-helpers.util";
import { getEffectiveOwnerId } from "@/lib/utils/organization-data";
import { logger } from "@/lib/logger";
import { createId } from "@paralleldrive/cuid2";
import { ApiResponses } from "@/lib/utils/api-response.util";
import { withRateLimit, rateLimiters } from "@/lib/rate-limiter";
import { getErrorMessage } from "@/lib/errors";
import { getDataSource } from "@/lib/data-source";
import { withCSRF } from "@/lib/csrf";

export const dynamic = "force-dynamic";

/**
 * GET /api/real-estate/clients
 * List client requirements. Filter by isActive. Include match count.
 */
export const GET = withRateLimit(async (request: NextRequest) => {
  try {
    const userEmail = await getAuthenticatedEmail(request, auth);
    if (!userEmail) {
      return ApiResponses.unauthorized();
    }

    const user = await prisma.users.findUnique({
      where: { email: userEmail },
      select: { id: true },
    });
    if (!user) {
      return ApiResponses.notFound("User not found");
    }

    const effectiveUserId = await getEffectiveOwnerId(user.id);

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

        const isActiveParam = request.nextUrl.searchParams.get("isActive");
        const isActive =
          isActiveParam === null ? true : isActiveParam === "true";

        const clients = await convexQuery("real_estate/queries:getClients", {
          userId: effectiveUserId,
          isActive,
        });

        if (clients) {
          return ApiResponses.success({ clients });
        }
      } catch (error) {
        console.error("[Convex fallback] real_estate clients GET:", error);
        // Fall through to Prisma
      }
    }

    const isActiveParam = request.nextUrl.searchParams.get("isActive");
    const isActive = isActiveParam === null ? true : isActiveParam === "true";

    const clients = await prisma.clientRequirements.findMany({
      where: {
        userId: effectiveUserId,
        isActive,
      },
      include: {
        _count: {
          select: { matches: true },
        },
      },
      orderBy: { createdAt: "desc" },
    });

    const enriched = clients.map((client) => ({
      ...client,
      matchCount: client._count.matches,
      _count: undefined,
    }));

    return ApiResponses.success({ clients: enriched });
  } catch (error) {
    logger.error("[Clients API] GET error", {
      error: getErrorMessage(error),
    });
    return ApiResponses.serverError("Failed to fetch client requirements");
  }
}, rateLimiters.authGeneral);

/**
 * POST /api/real-estate/clients
 * Create client requirements.
 */
export const POST = withRateLimit(
  withCSRF(async (request: NextRequest) => {
    try {
      const userEmail = await getAuthenticatedEmail(request, auth);
      if (!userEmail) {
        return ApiResponses.unauthorized();
      }

      const user = await prisma.users.findUnique({
        where: { email: userEmail },
        select: { id: true },
      });
      if (!user) {
        return ApiResponses.notFound("User not found");
      }

      const effectiveUserId = await getEffectiveOwnerId(user.id);
      const body = await request.json();

      // Validate required fields
      if (
        !body.clientName ||
        typeof body.clientName !== "string" ||
        body.clientName.trim().length === 0
      ) {
        return ApiResponses.badRequest("clientName is required");
      }
      if (
        !body.clientPhone ||
        typeof body.clientPhone !== "string" ||
        body.clientPhone.trim().length === 0
      ) {
        return ApiResponses.badRequest("clientPhone is required");
      }

      // Budget validation
      if (body.minBudget !== undefined && body.maxBudget !== undefined) {
        if (
          typeof body.minBudget === "number" &&
          typeof body.maxBudget === "number" &&
          body.minBudget > body.maxBudget
        ) {
          return ApiResponses.badRequest("minBudget cannot exceed maxBudget");
        }
      }
      if (body.minBedrooms !== undefined && body.maxBedrooms !== undefined) {
        if (
          typeof body.minBedrooms === "number" &&
          typeof body.maxBedrooms === "number" &&
          body.minBedrooms > body.maxBedrooms
        ) {
          return ApiResponses.badRequest(
            "minBedrooms cannot exceed maxBedrooms",
          );
        }
      }

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

          const clientId = await convexMutation(
            "real_estate/mutations:createClient",
            {
              userId: effectiveUserId,
              clientName: body.clientName.trim(),
              clientPhone: body.clientPhone.trim(),
              clientEmail: body.clientEmail?.trim(),
              listingType: body.listingType,
              propertyTypes: body.propertyTypes || [],
              minBedrooms: body.minBedrooms,
              maxBedrooms: body.maxBedrooms,
              minBudget: body.minBudget,
              maxBudget: body.maxBudget,
              currency: body.currency || "QAR",
              preferredAreas: body.preferredAreas || [],
              mustHaves: body.mustHaves || [],
              timeline: body.timeline?.trim(),
              purpose: body.purpose?.trim(),
              financingType: body.financingType?.trim(),
            },
          );

          if (clientId) {
            logger.info(
              "[Clients API] Client requirements created via Convex",
              {
                clientId,
                userId: effectiveUserId,
              },
            );
            return ApiResponses.success({ client: { id: clientId } });
          }
        } catch (error) {
          console.error("[Convex fallback] real_estate clients POST:", error);
          // Fall through to Prisma
        }
      }

      // Look up organizationId
      const membership = await prisma.organization_members.findFirst({
        where: { userId: user.id },
        select: { organizationId: true },
      });

      const client = await prisma.clientRequirements.create({
        data: {
          id: createId(),
          userId: effectiveUserId,
          organizationId: membership?.organizationId || null,
          clientName: body.clientName.trim(),
          clientPhone: body.clientPhone.trim(),
          clientEmail: body.clientEmail?.trim() || null,
          listingType: body.listingType || null,
          propertyTypes: body.propertyTypes || [],
          minBedrooms: body.minBedrooms ?? null,
          maxBedrooms: body.maxBedrooms ?? null,
          minBudget: body.minBudget ?? null,
          maxBudget: body.maxBudget ?? null,
          currency: body.currency || "QAR",
          preferredAreas: body.preferredAreas || [],
          mustHaves: body.mustHaves || [],
          timeline: body.timeline?.trim() || null,
          purpose: body.purpose?.trim() || null,
          financingType: body.financingType?.trim() || null,
        },
      });

      logger.info("[Clients API] Client requirements created", {
        clientId: client.id,
        userId: effectiveUserId,
      });

      return ApiResponses.success({ client });
    } catch (error) {
      logger.error("[Clients API] POST error", {
        error: getErrorMessage(error),
      });
      return ApiResponses.serverError("Failed to create client requirements");
    }
  }),
  rateLimiters.authGeneral,
);
