import { NextRequest, NextResponse } from "next/server";
import { z } from "zod";
import { requireAuth, RoleError } from "@/lib/auth";
import { prisma } from "@/lib/db";
import {
  sendSupportTicketEmail,
  type SupportTicketCategory,
} from "@/lib/email-sender";

const supportSchema = z.object({
  subject: z.string().trim().min(3).max(120),
  category: z.enum(["bug", "question", "feature", "billing", "other"]),
  message: z.string().trim().min(10).max(5000),
  pageUrl: z.string().trim().max(500).optional().nullable(),
});

// Simple in-memory rate limit: max 5 submissions per 10 minutes per user.
const WINDOW_MS = 10 * 60 * 1000;
const MAX_PER_WINDOW = 5;
const rateBucket = new Map<string, number[]>();

function rateLimit(key: string): { ok: boolean; retryAfterSeconds?: number } {
  const now = Date.now();
  const timestamps = rateBucket.get(key) || [];
  const recent = timestamps.filter((t) => now - t < WINDOW_MS);
  if (recent.length >= MAX_PER_WINDOW) {
    const oldest = recent[0];
    const retry = Math.ceil((WINDOW_MS - (now - oldest)) / 1000);
    return { ok: false, retryAfterSeconds: retry };
  }
  recent.push(now);
  rateBucket.set(key, recent);
  return { ok: true };
}

export async function POST(req: NextRequest) {
  try {
    const user = await requireAuth();

    const limit = rateLimit(`support:${user.id}`);
    if (!limit.ok) {
      return NextResponse.json(
        {
          error:
            "You've submitted too many support requests. Please try again shortly.",
          retryAfterSeconds: limit.retryAfterSeconds,
        },
        { status: 429 }
      );
    }

    const body = await req.json().catch(() => null);
    const parsed = supportSchema.safeParse(body);
    if (!parsed.success) {
      return NextResponse.json(
        {
          error: "Invalid support request",
          details: parsed.error.flatten(),
        },
        { status: 400 }
      );
    }

    const { subject, category, message, pageUrl } = parsed.data;

    // Resolve org name if the user has one
    let orgName: string | null = null;
    if (user.orgId) {
      const org = await prisma.organization.findUnique({
        where: { id: user.orgId },
        select: { name: true },
      });
      orgName = org?.name ?? null;
    }

    const userAgent = req.headers.get("user-agent");

    await sendSupportTicketEmail({
      subject,
      message,
      category: category as SupportTicketCategory,
      userEmail: user.email,
      userName: user.displayName || user.username || null,
      userId: user.id,
      orgId: user.orgId || null,
      orgName,
      pageUrl: pageUrl || null,
      userAgent,
      appEnv: process.env.NEXT_PUBLIC_ENV || null,
    });

    return NextResponse.json({ ok: true });
  } catch (error) {
    if (error instanceof RoleError) {
      return NextResponse.json(
        { error: "Authentication required" },
        { status: 401 }
      );
    }
    console.error("[api/support] Error:", error);
    return NextResponse.json(
      { error: "Failed to submit support request" },
      { status: 500 }
    );
  }
}
