/**
 * Viewing Bulk Import API
 * POST /api/real-estate/viewings/import
 *   Accepts pre-parsed array of viewing objects (frontend parses CSV).
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { getAuthenticatedUser } from "@/lib/utils/auth-helpers.util";
import { logger } from "@/lib/logger";
import { convexMutation } from "@/lib/convex-client";
import { withCSRF } from "@/lib/csrf";
import { withRateLimit, rateLimiters } from "@/lib/rate-limiter";

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

export const dynamic = "force-dynamic";

const MAX_IMPORT = 100;

const TIME_RE = /^\d{2}:\d{2}$/;
const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;

const VALID_VIEWING_TYPES = [
  "INDIVIDUAL",
  "TOUR",
  "OPEN_HOUSE",
  "VIRTUAL",
  "SECOND_VIEWING",
  "DEVELOPER_VISIT",
  "AREA_TOUR",
];

interface ImportViewingRow {
  propertyId?: string;
  clientName?: string;
  clientPhone?: string;
  clientEmail?: string;
  viewingType?: string;
  viewingDate?: string;
  viewingTime?: string;
  duration?: number | string;
}

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

    const body = await request.json();
    const { viewings } = body as { viewings?: unknown[] };

    if (!Array.isArray(viewings) || viewings.length === 0) {
      return NextResponse.json(
        { success: false, error: "viewings must be a non-empty array" },
        { status: 400 },
      );
    }

    if (viewings.length > MAX_IMPORT) {
      return NextResponse.json(
        {
          success: false,
          error: `Cannot import more than ${MAX_IMPORT} viewings at once`,
        },
        { status: 400 },
      );
    }

    const errors: string[] = [];
    let imported = 0;

    for (let i = 0; i < viewings.length; i++) {
      const row = viewings[i] as ImportViewingRow;
      const rowLabel = `Row ${i + 1}`;

      const propertyId = row.propertyId ? String(row.propertyId).trim() : "";
      if (!propertyId) {
        errors.push(`${rowLabel}: propertyId is required`);
        continue;
      }

      const clientName = row.clientName ? String(row.clientName).trim() : "";
      if (!clientName) {
        errors.push(`${rowLabel}: clientName is required`);
        continue;
      }

      const clientPhone = row.clientPhone
        ? String(row.clientPhone).trim()
        : "";
      if (!clientPhone) {
        errors.push(`${rowLabel}: clientPhone is required`);
        continue;
      }

      const viewingDateStr = row.viewingDate
        ? String(row.viewingDate).trim()
        : "";
      if (!viewingDateStr || !DATE_RE.test(viewingDateStr)) {
        errors.push(`${rowLabel}: viewingDate must be YYYY-MM-DD format`);
        continue;
      }
      const viewingDate = new Date(viewingDateStr).getTime();
      if (isNaN(viewingDate)) {
        errors.push(`${rowLabel}: viewingDate is not a valid date`);
        continue;
      }

      const viewingTime = row.viewingTime
        ? String(row.viewingTime).trim()
        : "";
      if (!viewingTime || !TIME_RE.test(viewingTime)) {
        errors.push(`${rowLabel}: viewingTime must be HH:MM format`);
        continue;
      }

      const viewingType = row.viewingType
        ? String(row.viewingType).trim().toUpperCase()
        : "INDIVIDUAL";
      if (!VALID_VIEWING_TYPES.includes(viewingType)) {
        errors.push(
          `${rowLabel}: invalid viewingType "${row.viewingType}". Valid: ${VALID_VIEWING_TYPES.join(", ")}`,
        );
        continue;
      }

      const duration = row.duration ? Number(row.duration) : 30;
      if (isNaN(duration) || duration < 1) {
        errors.push(`${rowLabel}: duration must be a positive number`);
        continue;
      }

      try {
        await convexMutation("real_estate/mutations:scheduleViewing", {
          userId: user.userId,
          propertyId,
          clientName,
          clientPhone,
          clientEmail: row.clientEmail
            ? String(row.clientEmail).trim()
            : undefined,
          viewingType,
          viewingDate,
          viewingTime,
          duration,
        });
        imported++;
      } catch (err) {
        errors.push(
          `${rowLabel}: failed to create - ${err instanceof Error ? err.message : "unknown error"}`,
        );
      }
    }

    log.info("Viewing bulk import completed", {
      userId: user.userId,
      requested: viewings.length,
      imported,
      errorCount: errors.length,
    });

    return NextResponse.json({ success: true, imported, errors });
  } catch (error) {
    log.error("Failed to bulk import viewings", error);
    return NextResponse.json(
      { success: false, error: "Internal server error" },
      { status: 500 },
    );
  }
}

export const POST = withRateLimit(
  withCSRF(postHandler),
  rateLimiters.authGeneral,
);
