/**
 * Individual Booking Note API
 * PATCH - Updates a specific note
 * DELETE - Deletes a specific note
 *
 * Only the author of the note can edit/delete it
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { prisma } from "@/lib/db";
import { validateCSRFToken } from "@/lib/csrf";
import { getAuthenticatedEmail } from "@/lib/utils/auth-helpers.util";
import { logger } from "@/lib/logger";
import { bookingNoteUpdateSchema } from "@/lib/validators/api-schemas";

export const dynamic = "force-dynamic";

/**
 * PATCH /api/bookings/[id]/notes/[noteId]
 * Updates a specific note (only by the author)
 */
export async function PATCH(
  request: NextRequest,
  { params }: { params: Promise<{ id: string; noteId: string }> },
) {
  try {
    const { id: bookingId, noteId } = await params;

    // Authenticate user
    const userEmail = await getAuthenticatedEmail(request, auth);

    if (!userEmail) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    // CSRF protection (bypass in development for easier testing)
    if (process.env.NODE_ENV !== "development") {
      const isValidCSRF = validateCSRFToken(request);
      if (!isValidCSRF) {
        return NextResponse.json(
          { success: false, error: "Invalid CSRF token" },
          { status: 403 },
        );
      }
    }

    // Get user
    const user = await prisma.users.findUnique({
      where: { email: userEmail },
      select: { id: true, role: true },
    });

    if (!user) {
      return NextResponse.json(
        { success: false, error: "User not found" },
        { status: 404 },
      );
    }

    // Verify the booking exists and user has access
    const booking = await prisma.bookings.findFirst({
      where: {
        id: bookingId,
        userId: user.id,
      },
      select: { id: true },
    });

    if (!booking) {
      return NextResponse.json(
        { success: false, error: "Booking not found or access denied" },
        { status: 404 },
      );
    }

    // Find the note and verify ownership
    const existingNote = await bookingNotesAdapter.findFirst({
      where: {
        id: noteId,
        bookingId,
      },
    });

    if (!existingNote) {
      return NextResponse.json(
        { success: false, error: "Note not found" },
        { status: 404 },
      );
    }

    // Only the author can edit their note
    if (existingNote.authorId !== user.id) {
      return NextResponse.json(
        { success: false, error: "You can only edit your own notes" },
        { status: 403 },
      );
    }

    // Parse and validate request body
    const body = await request.json();
    const parsed = bookingNoteUpdateSchema.safeParse(body);

    if (!parsed.success) {
      return NextResponse.json(
        { success: false, error: parsed.error.errors.map(e => e.message).join(", ") },
        { status: 400 },
      );
    }

    const { content } = parsed.data;

    // Update the note
    const note = await bookingNotesAdapter.update({
      where: { id: noteId },
      data: {
        content,
      },
    });

    logger.info("Booking note updated", {
      noteId,
      bookingId,
      authorId: user.id,
    });

    return NextResponse.json({
      success: true,
      note,
    });
  } catch (error) {
    logger.error("Failed to update booking note", {
      error: error instanceof Error ? error.message : "Unknown error",
    });

    return NextResponse.json(
      { success: false, error: "Failed to update booking note" },
      { status: 500 },
    );
  }
}

/**
 * DELETE /api/bookings/[id]/notes/[noteId]
 * Deletes a specific note (only by the author)
 */
export async function DELETE(
  request: NextRequest,
  { params }: { params: Promise<{ id: string; noteId: string }> },
) {
  try {
    const { id: bookingId, noteId } = await params;

    // Authenticate user
    const userEmail = await getAuthenticatedEmail(request, auth);

    if (!userEmail) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    // CSRF protection (bypass in development for easier testing)
    if (process.env.NODE_ENV !== "development") {
      const isValidCSRF = validateCSRFToken(request);
      if (!isValidCSRF) {
        return NextResponse.json(
          { success: false, error: "Invalid CSRF token" },
          { status: 403 },
        );
      }
    }

    // Get user
    const user = await prisma.users.findUnique({
      where: { email: userEmail },
      select: { id: true, role: true },
    });

    if (!user) {
      return NextResponse.json(
        { success: false, error: "User not found" },
        { status: 404 },
      );
    }

    // Verify the booking exists and user has access
    const booking = await prisma.bookings.findFirst({
      where: {
        id: bookingId,
        userId: user.id,
      },
      select: { id: true },
    });

    if (!booking) {
      return NextResponse.json(
        { success: false, error: "Booking not found or access denied" },
        { status: 404 },
      );
    }

    // Find the note and verify ownership
    const existingNote = await bookingNotesAdapter.findFirst({
      where: {
        id: noteId,
        bookingId,
      },
    });

    if (!existingNote) {
      return NextResponse.json(
        { success: false, error: "Note not found" },
        { status: 404 },
      );
    }

    // Only the author can delete their note
    if (existingNote.authorId !== user.id) {
      return NextResponse.json(
        { success: false, error: "You can only delete your own notes" },
        { status: 403 },
      );
    }

    // Delete the note
    await bookingNotesAdapter.delete({
      where: { id: noteId },
    });

    logger.info("Booking note deleted", {
      noteId,
      bookingId,
      authorId: user.id,
    });

    return NextResponse.json({
      success: true,
      message: "Note deleted successfully",
    });
  } catch (error) {
    logger.error("Failed to delete booking note", {
      error: error instanceof Error ? error.message : "Unknown error",
    });

    return NextResponse.json(
      { success: false, error: "Failed to delete booking note" },
      { status: 500 },
    );
  }
}
