import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/infrastructure/db/prisma";
import { checkRateLimit } from "@/lib/rate-limiter";
import { patientSchema } from "@/lib/validations";

export async function POST(request: NextRequest) {
  try {
    const body = await request.json();

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

    const { phone, name, email } = validationResult.data;

    const ip =
      request.ip ||
      request.headers.get("x-forwarded-for")?.split(",")[0] ||
      request.headers.get("x-real-ip") ||
      "unknown";

    // Check rate limit by IP
    const ipLimit = await checkRateLimit(ip, "ip");
    if (!ipLimit.success) {
      return NextResponse.json(
        {
          error: "Too many requests",
          limit: ipLimit.limit,
          remaining: ipLimit.remaining,
          resetTime: ipLimit.resetTime,
        },
        {
          status: 429,
          headers: {
            "X-RateLimit-Limit": ipLimit.limit.toString(),
            "X-RateLimit-Remaining": ipLimit.remaining.toString(),
            "X-RateLimit-Reset": ipLimit.resetTime.toISOString(),
          },
        }
      );
    }

    // Check rate limit by phone
    const phoneLimit = await checkRateLimit(phone, "phone");
    if (!phoneLimit.success) {
      return NextResponse.json(
        {
          error: "Too many requests for this phone number",
          limit: phoneLimit.limit,
          remaining: phoneLimit.remaining,
          resetTime: phoneLimit.resetTime,
        },
        {
          status: 429,
          headers: {
            "X-RateLimit-Limit": phoneLimit.limit.toString(),
            "X-RateLimit-Remaining": phoneLimit.remaining.toString(),
            "X-RateLimit-Reset": phoneLimit.resetTime.toISOString(),
          },
        }
      );
    }

    // Check if patient already exists
    const existingPatient = await prisma.patient.findUnique({
      where: { phone },
    });

    if (existingPatient) {
      return NextResponse.json(
        {
          error: "Patient already exists",
          phone: existingPatient.phone,
        },
        { status: 409 }
      );
    }

    // Create new patient
    const patient = await prisma.patient.create({
      data: {
        phone,
        name,
        email: email || null,
        birthdate: new Date("2000-01-01"), // Default value, will be updated later
        status: "active",
      },
      select: {
        phone: true,
        name: true,
        email: true,
        status: true,
        createdAt: true,
      },
    });

    // Rate limit headers for successful response
    const headers = {
      "X-RateLimit-Limit": phoneLimit.limit.toString(),
      "X-RateLimit-Remaining": phoneLimit.remaining.toString(),
      "X-RateLimit-Reset": phoneLimit.resetTime.toISOString(),
    };

    return NextResponse.json(
      {
        success: true,
        message: "Patient registered successfully",
        patient,
      },
      { status: 201, headers }
    );
  } catch (error) {
    console.error("Patient registration error:", error);

    // Handle Prisma unique constraint violation
    if (error instanceof Error && error.message.includes("Unique constraint")) {
      return NextResponse.json(
        {
          error: "Patient already exists",
        },
        { status: 409 }
      );
    }

    return NextResponse.json({ error: "Internal server error" }, { status: 500 });
  }
}
