import { Request, Response } from 'express';
import prisma from '../config/database';
import { sendSuccess, sendError } from '../utils/response.utils';
import { AuthenticatedRequest } from '../middleware/auth.middleware';

// Simple Spam Detection filter
const containsSpamOrProfanity = (text: string): boolean => {
  const forbidden = ['casino', 'viagra', 'crypto-scam', 'free-money', 'hack-pass'];
  const lower = text.toLowerCase();
  return forbidden.some((word) => lower.includes(word));
};

// 1. Submit New Customer Review
export const createReview = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const userId = req.user?.userId;
    if (!userId) return sendError(res, 'Unauthorized', null, 401);

    const { bookId, rating, title, comment, images = [] } = req.body;

    // Check if user has purchased this book (Verified Purchase check)
    const userOrder = await prisma.order.findFirst({
      where: {
        userId,
        status: { in: ['DELIVERED', 'SHIPPED', 'CONFIRMED'] },
        items: { some: { bookId } },
      },
    });

    const isVerifiedPurchase = !!userOrder;

    // Automated Spam Detection
    const isSpam = containsSpamOrProfanity(comment) || (title && containsSpamOrProfanity(title));
    const isApproved = !isSpam; // Auto-flag spam for moderation

    const review = await prisma.review.create({
      data: {
        bookId,
        userId,
        rating: Number(rating),
        title,
        comment,
        isVerifiedPurchase,
        isApproved,
        isFlagged: isSpam,
        images,
      },
      include: {
        user: { select: { firstName: true, lastName: true, avatarUrl: true } },
      },
    });

    // Re-calculate Book Average Rating
    const agg = await prisma.review.aggregate({
      where: { bookId, isApproved: true },
      _avg: { rating: true },
      _count: { rating: true },
    });

    const newAvg = agg._avg.rating ? Number(agg._avg.rating.toFixed(2)) : rating;
    const newCount = agg._count.rating || 1;

    await prisma.book.update({
      where: { id: bookId },
      data: {
        ratingAverage: newAvg,
        ratingCount: newCount,
      },
    });

    return sendSuccess(
      res,
      isSpam ? 'Review submitted and sent for moderation.' : 'Review published successfully!',
      review,
      201
    );
  } catch (error: any) {
    return sendError(res, 'Failed to submit review', error.message, 500);
  }
};

// 2. Get Book Reviews & Rating Analytics Breakdown
export const getBookReviews = async (req: Request, res: Response) => {
  try {
    const { bookId } = req.params;
    const { page = 1, limit = 10, ratingFilter } = req.query;

    const take = Number(limit);
    const skip = (Number(page) - 1) * take;

    const where: any = { bookId, isApproved: true };
    if (ratingFilter) where.rating = Number(ratingFilter);

    const [reviews, total, ratingCounts] = await Promise.all([
      prisma.review.findMany({
        where,
        take,
        skip,
        include: {
          user: { select: { id: true, firstName: true, lastName: true, avatarUrl: true } },
        },
        orderBy: { createdAt: 'desc' },
      }),
      prisma.review.count({ where }),
      prisma.review.groupBy({
        by: ['rating'],
        where: { bookId, isApproved: true },
        _count: { rating: true },
      }),
    ]);

    // Calculate rating percentages (5-star down to 1-star)
    const breakdown = { 5: 0, 4: 0, 3: 0, 2: 0, 1: 0 };
    let totalReviewsSum = 0;
    ratingCounts.forEach((r) => {
      (breakdown as any)[r.rating] = r._count.rating;
      totalReviewsSum += r._count.rating;
    });

    const percentages = {
      5: totalReviewsSum ? Math.round(((breakdown[5] || 0) / totalReviewsSum) * 100) : 0,
      4: totalReviewsSum ? Math.round(((breakdown[4] || 0) / totalReviewsSum) * 100) : 0,
      3: totalReviewsSum ? Math.round(((breakdown[3] || 0) / totalReviewsSum) * 100) : 0,
      2: totalReviewsSum ? Math.round(((breakdown[2] || 0) / totalReviewsSum) * 100) : 0,
      1: totalReviewsSum ? Math.round(((breakdown[1] || 0) / totalReviewsSum) * 100) : 0,
    };

    return sendSuccess(res, 'Book reviews & analytics retrieved', {
      reviews,
      analytics: {
        totalReviews: totalReviewsSum,
        breakdown,
        percentages,
      },
      pagination: {
        total,
        page: Number(page),
        limit: take,
        totalPages: Math.ceil(total / take),
      },
    });
  } catch (error: any) {
    return sendError(res, 'Error fetching reviews', error.message, 500);
  }
};

// 3. Upvote Helpful Review
export const voteHelpfulReview = async (req: Request, res: Response) => {
  try {
    const { id } = req.params;

    const review = await prisma.review.update({
      where: { id },
      data: {
        helpfulVotes: { increment: 1 },
      },
    });

    return sendSuccess(res, 'Voted helpful successfully', { helpfulVotes: review.helpfulVotes });
  } catch (error: any) {
    return sendError(res, 'Failed to vote review', error.message, 500);
  }
};

// 4. Admin Reply to Review
export const adminReplyToReview = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { id } = req.params;
    const { adminReply } = req.body;

    const review = await prisma.review.update({
      where: { id },
      data: { adminReply },
    });

    return sendSuccess(res, 'Admin reply published', review);
  } catch (error: any) {
    return sendError(res, 'Failed to reply to review', error.message, 500);
  }
};

// 5. Admin Moderation Queue (Approve / Flag / Delete)
export const moderateReview = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { id } = req.params;
    const { isApproved, isFlagged } = req.body;

    const review = await prisma.review.update({
      where: { id },
      data: {
        ...(isApproved !== undefined && { isApproved }),
        ...(isFlagged !== undefined && { isFlagged }),
      },
    });

    return sendSuccess(res, 'Review moderation updated', review);
  } catch (error: any) {
    return sendError(res, 'Moderation update failed', error.message, 500);
  }
};
