import { NextRequest, NextResponse } from "next/server";
import { getCurrentUser } from "@/lib/auth-utils";
import prisma from "@/lib/db";
import { z } from "zod";

const updateTourSchema = z.object({
  title: z.string().min(5, "Title must be at least 5 characters").optional(),
  description: z
    .string()
    .min(20, "Description must be at least 20 characters")
    .optional(),
  city: z.string().min(2, "City is required").optional(),
  meetingPoint: z.string().optional().nullable(),
  meetingPointLat: z.number().optional().nullable(),
  meetingPointLng: z.number().optional().nullable(),
  durationMin: z
    .number()
    .min(30, "Duration must be at least 30 minutes")
    .optional(),
  priceCents: z.number().min(0, "Price must be positive").optional(),
  maxGuests: z
    .number()
    .min(1, "At least 1 guest required")
    .max(100)
    .optional(),
  included: z.array(z.string()).optional(),
  tags: z.array(z.string()).optional(),
  published: z.boolean().optional(),
});

type RouteContext = {
  params: Promise<{ id: string }>;
};

// Get a single tour (for editing)
export async function GET(req: NextRequest, context: RouteContext) {
  try {
    const user = await getCurrentUser();

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

    const { id } = await context.params;

    const tour = await prisma.tour.findUnique({
      where: { id },
      include: {
        images: {
          orderBy: {
            order: "asc",
          },
        },
        createdBy: {
          select: {
            id: true,
            name: true,
            email: true,
            image: true,
          },
        },
        _count: {
          select: {
            bookings: true,
            reviews: true,
          },
        },
      },
    });

    if (!tour) {
      return NextResponse.json({ error: "Tour not found" }, { status: 404 });
    }

    // Check if user is the owner
    if (tour.createdById !== user.id) {
      return NextResponse.json(
        { error: "You don't have permission to view this tour" },
        { status: 403 }
      );
    }

    return NextResponse.json({ tour });
  } catch (error) {
    console.error("Error fetching tour:", error);
    return NextResponse.json(
      { error: "Failed to fetch tour" },
      { status: 500 }
    );
  }
}

// Update a tour
export async function PATCH(req: NextRequest, context: RouteContext) {
  try {
    const user = await getCurrentUser();

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

    if (user.role !== "GUIDE") {
      return NextResponse.json(
        { error: "Only guides can update tours" },
        { status: 403 }
      );
    }

    const { id } = await context.params;

    // Check if tour exists and user owns it
    const existingTour = await prisma.tour.findUnique({
      where: { id },
    });

    if (!existingTour) {
      return NextResponse.json({ error: "Tour not found" }, { status: 404 });
    }

    if (existingTour.createdById !== user.id) {
      return NextResponse.json(
        { error: "You don't have permission to update this tour" },
        { status: 403 }
      );
    }

    const body = await req.json();
    const validatedData = updateTourSchema.parse(body);

    // If title is being updated, regenerate slug
    const updateData: Record<string, unknown> = { ...validatedData };

    if (validatedData.title && validatedData.title !== existingTour.title) {
      const newSlug = validatedData.title
        .toLowerCase()
        .replace(/[^a-z0-9]+/g, "-")
        .replace(/(^-|-$)/g, "");

      // Check if new slug conflicts with another tour
      const slugConflict = await prisma.tour.findFirst({
        where: {
          slug: newSlug,
          id: { not: id },
        },
      });

      if (slugConflict) {
        updateData.slug = `${newSlug}-${Math.random().toString(36).substring(2, 8)}`;
      } else {
        updateData.slug = newSlug;
      }
    }

    const tour = await prisma.tour.update({
      where: { id },
      data: updateData,
      include: {
        images: {
          orderBy: {
            order: "asc",
          },
        },
        createdBy: {
          select: {
            id: true,
            name: true,
            email: true,
            image: true,
          },
        },
      },
    });

    return NextResponse.json({ tour });
  } catch (error) {
    if (error instanceof z.ZodError) {
      return NextResponse.json(
        { error: "Validation error", details: error.issues },
        { status: 400 }
      );
    }

    console.error("Error updating tour:", error);
    return NextResponse.json(
      { error: "Failed to update tour" },
      { status: 500 }
    );
  }
}

// Delete a tour (hard delete)
export async function DELETE(req: NextRequest, context: RouteContext) {
  try {
    const user = await getCurrentUser();

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

    if (user.role !== "GUIDE") {
      return NextResponse.json(
        { error: "Only guides can delete tours" },
        { status: 403 }
      );
    }

    const { id } = await context.params;

    // Check if tour exists and user owns it
    const existingTour = await prisma.tour.findUnique({
      where: { id },
      include: {
        bookings: true,
      },
    });

    if (!existingTour) {
      return NextResponse.json({ error: "Tour not found" }, { status: 404 });
    }

    if (existingTour.createdById !== user.id) {
      return NextResponse.json(
        { error: "You don't have permission to delete this tour" },
        { status: 403 }
      );
    }

    // Check if there are any confirmed bookings
    const hasConfirmedBookings = existingTour.bookings.some(
      (booking) => booking.status === "CONFIRMED"
    );

    if (hasConfirmedBookings) {
      return NextResponse.json(
        {
          error:
            "Cannot delete tour with confirmed bookings. Please archive it instead.",
        },
        { status: 400 }
      );
    }

    await prisma.tour.delete({
      where: { id },
    });

    return NextResponse.json({ message: "Tour deleted successfully" });
  } catch (error) {
    console.error("Error deleting tour:", error);
    return NextResponse.json(
      { error: "Failed to delete tour" },
      { status: 500 }
    );
  }
}
