import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireAuth } from "@/lib/auth";

// GET /api/souq/orders/[id] — order detail
export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const auth = await requireAuth(request);
    if (!auth) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const { id } = await params;

    const order = await prisma.purchase.findUnique({
      where: { id },
      include: {
        listing: {
          select: { id: true, title: true, category: true, subcategory: true, priceFlh: true, description: true, deliveryDays: true },
        },
        buyer: {
          select: { id: true, name: true, email: true, avatar: true },
        },
        seller: {
          select: { id: true, name: true, email: true, avatar: true },
        },
      },
    });

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

    // Verify user is either the buyer or seller
    if (order.buyerId !== auth.userId && order.sellerId !== auth.userId) {
      return NextResponse.json(
        { error: "Forbidden: you are not a party to this order" },
        { status: 403 }
      );
    }

    // Check if the current user (buyer) has already reviewed this order
    let hasReviewed = false;
    if (order.status === "completed" && order.buyerId === auth.userId) {
      const existingReview = await prisma.review.findFirst({
        where: { purchaseId: order.id, reviewerId: auth.userId },
        select: { id: true },
      });
      hasReviewed = !!existingReview;
    }

    // Parse JSON fields
    const data = order as any;
    return NextResponse.json({
      order: {
        ...data,
        messages: data.messages ? JSON.parse(data.messages) : [],
        deliveryFiles: data.deliveryFiles ? JSON.parse(data.deliveryFiles) : [],
      },
      hasReviewed,
    });
  } catch (error) {
    console.error("GET /api/souq/orders/[id] error:", error);
    return NextResponse.json(
      { error: "Internal server error" },
      { status: 500 }
    );
  }
}

// PATCH /api/souq/orders/[id] — update order status or add messages
export async function PATCH(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const auth = await requireAuth(request);
    if (!auth) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const { id } = await params;

    const order = await prisma.purchase.findUnique({
      where: { id },
    });

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

    // Verify user is either the buyer or seller
    if (order.buyerId !== auth.userId && order.sellerId !== auth.userId) {
      return NextResponse.json(
        { error: "Forbidden: you are not a party to this order" },
        { status: 403 }
      );
    }

    const body = await request.json();
    const { status: newStatus, message, deliveryFiles } = body;

    const updateData: Record<string, unknown> = {};

    // Update status if provided
    if (newStatus) {
      const validStatuses = [
        "pending",
        "paid",
        "in_progress",
        "delivered",
        "completed",
        "disputed",
        "cancelled",
      ];

      if (!validStatuses.includes(newStatus)) {
        return NextResponse.json(
          {
            error: `Invalid status. Must be one of: ${validStatuses.join(", ")}`,
          },
          { status: 400 }
        );
      }

      // Validate status transitions
      const validTransitions: Record<string, string[]> = {
        paid: ["in_progress", "cancelled"],
        in_progress: ["delivered", "disputed"],
        delivered: ["completed", "disputed"],
        completed: [],
        disputed: ["completed", "cancelled"],
        cancelled: [],
        pending: ["paid", "cancelled"],
      };

      const allowed = validTransitions[order.status] || [];
      if (!allowed.includes(newStatus)) {
        return NextResponse.json(
          {
            error: `Cannot transition from "${order.status}" to "${newStatus}"`,
          },
          { status: 400 }
        );
      }

      // Only seller can mark as in_progress or delivered
      if (
        (newStatus === "in_progress" || newStatus === "delivered") &&
        auth.userId !== order.sellerId
      ) {
        return NextResponse.json(
          { error: "Only the seller can update to this status" },
          { status: 403 }
        );
      }

      // Only buyer can mark as completed
      if (newStatus === "completed" && auth.userId !== order.buyerId) {
        return NextResponse.json(
          { error: "Only the buyer can mark an order as completed" },
          { status: 403 }
        );
      }

      updateData.status = newStatus;
    }

    // Add a message if provided
    if (message) {
      if (typeof message !== "string" || message.trim().length === 0) {
        return NextResponse.json(
          { error: "Message must be a non-empty string" },
          { status: 400 }
        );
      }

      const existingMessages = order.messages
        ? (JSON.parse(order.messages) as Array<Record<string, unknown>>)
        : [];

      const newMessage = {
        from: auth.userId,
        text: message.trim(),
        timestamp: new Date().toISOString(),
      };

      existingMessages.push(newMessage);
      updateData.messages = JSON.stringify(existingMessages);
    }

    // Update delivery files if provided
    if (deliveryFiles) {
      if (!Array.isArray(deliveryFiles)) {
        return NextResponse.json(
          { error: "deliveryFiles must be an array" },
          { status: 400 }
        );
      }
      updateData.deliveryFiles = JSON.stringify(deliveryFiles);
    }

    if (Object.keys(updateData).length === 0) {
      return NextResponse.json(
        { error: "No fields to update. Provide status, message, or deliveryFiles." },
        { status: 400 }
      );
    }

    const updated = await prisma.purchase.update({
      where: { id },
      data: updateData,
      include: {
        listing: {
          select: { id: true, title: true, category: true },
        },
        buyer: {
          select: { id: true, name: true, email: true, avatar: true },
        },
        seller: {
          select: { id: true, name: true, email: true, avatar: true },
        },
      },
    });

    const data = updated as any;
    return NextResponse.json({
      order: {
        ...data,
        messages: data.messages ? JSON.parse(data.messages) : [],
        deliveryFiles: data.deliveryFiles ? JSON.parse(data.deliveryFiles) : [],
      },
    });
  } catch (error) {
    console.error("PATCH /api/souq/orders/[id] error:", error);
    return NextResponse.json(
      { error: "Internal server error" },
      { status: 500 }
    );
  }
}
