/**
 * Bulk Review Requests API
 * POST - Create and send multiple review requests at once
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { getAuthenticatedUser } from "@/lib/utils/auth-helpers.util";
import { getEffectiveOwnerId } from "@/lib/utils/organization-data";
import {
  createReviewRequest,
  sendReviewRequest,
} from "@/lib/services/reviews.service";
import { BulkReviewRequestSchema } from "@/lib/validators/reviews.validator";
import { queueEmail } from "@/lib/queue/email-queue";
import { buildReviewRequestEmailHtml } from "@/lib/email/review-request-email";
import { logger } from "@/lib/logger";
import { getDataSource } from "@/lib/data-source";

const log = logger.scope("BulkReviewRequestsAPI");

export async function POST(request: NextRequest) {
  try {
    const user = await getAuthenticatedUser(request, auth);
    if (!user) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    const effectiveUserId = await getEffectiveOwnerId(user.userId);
    const body = await request.json();
    const parsed = BulkReviewRequestSchema.safeParse(body);

    if (!parsed.success) {
      return NextResponse.json(
        { success: false, error: parsed.error.flatten() },
        { status: 400 },
      );
    }

    if (getDataSource("reviews") === "convex") {
      try {
        const { convexMutation, convexQuery } = await import(
          "@/lib/convex-client"
        );

        // Look up business name once for all requests
        const widgetSettings = (await convexQuery(
          "reviews/queries:getWidgetSettings",
          { userId: effectiveUserId },
        ).catch(() => null)) as {
          businessName?: string;
          businessNameAr?: string;
        } | null;

        const results: Array<{
          customerName: string;
          success: boolean;
          requestId?: string;
          error?: string;
        }> = [];

        for (const item of parsed.data.requests) {
          try {
            const createResult = (await convexMutation(
              "reviews/mutations:createReviewRequest",
              {
                userId: effectiveUserId,
                customerName: item.customerName,
                customerEmail: item.customerEmail ?? undefined,
                customerPhone: item.customerPhone ?? undefined,
                channel: item.channel,
                message: parsed.data.message ?? undefined,
                language: parsed.data.language ?? undefined,
                bookingId: item.bookingId ?? undefined,
                customerId: item.customerId ?? undefined,
              },
            )) as { id: string; token: string } | null;

            if (createResult) {
              const sendResult = (await convexMutation(
                "reviews/mutations:sendReviewRequest",
                {
                  userId: effectiveUserId,
                  requestId: createResult.id,
                },
              )) as {
                id: string;
                customerEmail?: string;
                channel: string;
                token: string;
                language?: string;
                customerName: string;
              } | null;

              // Queue email if channel is email and customer has email
              if (
                sendResult?.customerEmail &&
                sendResult.channel === "email"
              ) {
                try {
                  const language =
                    (sendResult.language as "en" | "ar") || "en";
                  const reviewUrl = `${process.env.NEXT_PUBLIC_APP_URL || "https://mawidi.com"}/${language}/review/${sendResult.token}`;
                  const businessName =
                    (language === "ar"
                      ? widgetSettings?.businessNameAr
                      : widgetSettings?.businessName) ?? "Mawidi";

                  const email = buildReviewRequestEmailHtml({
                    customerName: sendResult.customerName,
                    businessName,
                    reviewUrl,
                    language,
                    isReminder: false,
                  });

                  await queueEmail({
                    to: sendResult.customerEmail,
                    subject: email.subject,
                    html: email.html,
                    text: email.text,
                    category: "review_request",
                    metadata: { reviewRequestId: String(sendResult.id) },
                  });
                } catch {
                  // Non-fatal — request was created and sent
                }
              }
            }

            results.push({
              customerName: item.customerName,
              success: true,
              requestId: createResult ? String(createResult.id) : undefined,
            });
          } catch (itemError) {
            const msg =
              itemError instanceof Error ? itemError.message : "Unknown error";
            results.push({
              customerName: item.customerName,
              success: false,
              error: msg,
            });
          }
        }

        const successCount = results.filter((r) => r.success).length;
        const failCount = results.filter((r) => !r.success).length;

        return NextResponse.json(
          {
            success: true,
            total: results.length,
            sent: successCount,
            failed: failCount,
            results,
          },
          { status: 201 },
        );
      } catch {
        // Fall through to Prisma
      }
    }

    const results: Array<{
      customerName: string;
      success: boolean;
      requestId?: string;
      error?: string;
    }> = [];

    for (const item of parsed.data.requests) {
      try {
        const reviewRequest = await createReviewRequest(effectiveUserId, {
          customerName: item.customerName,
          customerEmail: item.customerEmail ?? null,
          customerPhone: item.customerPhone ?? null,
          channel: item.channel,
          message: parsed.data.message ?? null,
          language: parsed.data.language,
          source: "manual",
          bookingId: item.bookingId ?? null,
        });

        // Send the request (marks status as SENT, returns full data)
        const sendResult = await sendReviewRequest(
          effectiveUserId,
          reviewRequest.id,
        );

        // Queue email if channel is email and customer has email
        if (sendResult?.customerEmail && sendResult.channel === "email") {
          try {
            const language = (sendResult.language as "en" | "ar") || "en";
            const reviewUrl = `${process.env.NEXT_PUBLIC_APP_URL || "https://mawidi.com"}/${language}/review/${sendResult.token}`;

            const email = buildReviewRequestEmailHtml({
              customerName: sendResult.customerName,
              businessName: "Mawidi",
              reviewUrl,
              language,
              isReminder: false,
            });

            await queueEmail({
              to: sendResult.customerEmail,
              subject: email.subject,
              html: email.html,
              text: email.text,
              category: "review_request",
              metadata: { reviewRequestId: sendResult.id },
            });
          } catch {
            // Non-fatal — request was created and sent
          }
        }

        results.push({
          customerName: item.customerName,
          success: true,
          requestId: reviewRequest.id,
        });
      } catch (itemError) {
        const msg =
          itemError instanceof Error ? itemError.message : "Unknown error";
        log.error("Failed to create bulk review request item", {
          customerName: item.customerName,
          error: msg,
        });
        results.push({
          customerName: item.customerName,
          success: false,
          error: msg,
        });
      }
    }

    const successCount = results.filter((r) => r.success).length;
    const failCount = results.filter((r) => !r.success).length;

    return NextResponse.json(
      {
        success: true,
        total: results.length,
        sent: successCount,
        failed: failCount,
        results,
      },
      { status: 201 },
    );
  } catch (error) {
    log.error("Failed to process bulk review requests", error);
    return NextResponse.json(
      { success: false, error: "Internal server error" },
      { status: 500 },
    );
  }
}
