import { Request, Response } from "express";
import { isValidObjectId, Types } from "mongoose";
import order from "../../models/order";
import review from "../../models/review";

const getUserOrders = async (req: Request, res: Response) => {
  const { page = 1, perPage = 10 } = req.query;
  const { id } = req.params;

  if (!isValidObjectId(id)) {
    return res.status(400).json({
      message: "User ID is not valid",
    });
  }

  try {
    const filter = { user: id };
    const [orders, totalItemCount] = await Promise.all([
      order
        .find(filter)
        .sort({ createdAt: -1 })
        .skip((Number(page) - 1) * Number(perPage))
        .limit(Number(perPage)),
      order.countDocuments(filter),
    ]);

    // The logged-in customer's own review per order item. aggregate() skips
    // the Review find-hooks that auto-populate user/product.
    const ownReviews = await review.aggregate([
      {
        $match: {
          order: { $in: orders.map((o: any) => o._id) },
          user: new Types.ObjectId(id),
          isDeleted: { $ne: true },
        },
      },
      {
        $project: { order: 1, product: 1, rating: 1, comment: 1, createdAt: 1, updatedAt: 1 },
      },
    ]);
    const reviewMap = new Map<string, any>();
    for (const r of ownReviews) {
      reviewMap.set(`${r.order}_${r.product}`, {
        _id: r._id,
        rating: r.rating,
        comment: r.comment,
        createdAt: r.createdAt,
        updatedAt: r.updatedAt,
      });
    }

    const ordersWithReview = orders.map((o: any) => {
      const obj = o.toJSON();
      obj.gifts = (obj.gifts || []).map((g: any) => ({
        ...g,
        review:
          reviewMap.get(`${obj._id}_${String(g.product?._id ?? g.product)}`) ??
          null,
      }));
      return obj;
    });

    res.status(200).json({ orders: ordersWithReview, totalItemCount });
  } catch (err) {
    res.status(500).json({ message: err });
  }
};

export = { getUserOrders };
