const express = require('express');
const { v4: uuidv4 } = require('uuid');
const router = express.Router();

module.exports = (pool, query, authMiddleware) => {
  // Apply authentication middleware to all routes
  router.use(authMiddleware);
  
  // Get reviews for a specific product
  router.get('/:productId', async (req, res, next) => {
    try {
      const { productId } = req.params;
      
      // Get all approved reviews with user info and replies
      const reviewsQuery = `
        SELECT 
          r.id, r.title, r.content, r.rating, r.is_verified_purchase,
          r.created_at, r.parent_id,
          u.id as user_id, u.first_name, u.last_name
        FROM product_reviews r
        JOIN users u ON r.user_id = u.id
        WHERE r.product_id = $1 AND r.is_approved = true
        ORDER BY r.created_at DESC
      `;
      
      const reviewsResult = await query(reviewsQuery, [productId]);
      
      // Organize reviews into threads
      const reviewThreads = [];
      const reviewMap = {};
      
      // First, create a map of all reviews
      reviewsResult.rows.forEach(review => {
        reviewMap[review.id] = {
          ...review,
          replies: []
        };
      });
      
      // Then, organize into threads
      reviewsResult.rows.forEach(review => {
        if (review.parent_id) {
          // This is a reply
          if (reviewMap[review.parent_id]) {
            reviewMap[review.parent_id].replies.push(reviewMap[review.id]);
          }
        } else {
          // This is a top-level review
          reviewThreads.push(reviewMap[review.id]);
        }
      });
      
      res.json(reviewThreads);
    } catch (error) {
      next(error);
    }
  });
  
  // Add a review to a product
  router.post('/:productId', async (req, res, next) => {
    try {
      const { productId } = req.params;
      const { title, content, rating, parentId } = req.body;
      const userId = req.user.id;
      
      // Validate required fields
      if (!title) {
        return res.status(400).json({
          error: true,
          message: 'Review title is required'
        });
      }
      
      // If it's a top-level review, rating is required
      if (!parentId && (!rating || rating < 1 || rating > 5)) {
        return res.status(400).json({
          error: true,
          message: 'Valid rating (1-5) is required for reviews'
        });
      }
      
      // Check if product exists
      const productCheck = await query(
        'SELECT id FROM products WHERE id = $1',
        [productId]
      );
      
      if (productCheck.rows.length === 0) {
        return res.status(404).json({
          error: true,
          message: 'Product not found'
        });
      }
      
      // If this is a reply, check if parent review exists
      if (parentId) {
        const parentCheck = await query(
          'SELECT id FROM product_reviews WHERE id = $1 AND product_id = $2',
          [parentId, productId]
        );
        
        if (parentCheck.rows.length === 0) {
          return res.status(404).json({
            error: true,
            message: 'Parent review not found'
          });
        }
      }
      
      // Check if user has purchased the product
      const purchaseCheck = await query(`
        SELECT o.id 
        FROM orders o
        JOIN order_items oi ON o.id = oi.order_id
        WHERE o.user_id = $1 
        AND oi.product_id = $2
        AND o.payment_completed = true
        LIMIT 1
      `, [userId, productId]);
      
      const isVerifiedPurchase = purchaseCheck.rows.length > 0;
      
      
      const isAdmin = req.user.is_admin || false;
      
      // Only allow reviews if user has purchased the product or is an admin
      if (!isVerifiedPurchase && !isAdmin && !parentId) {
        return res.status(403).json({
          error: true,
          message: 'You must purchase this product before you can review it'
        });
      }
      
      // For replies, we don't need verified purchase
      const isApproved = isAdmin ? true : false; // Auto-approve admin reviews
      const reviewData = {
        id: uuidv4(),
        productId,
        userId,
        parentId: parentId || null,
        title,
        content: content || null,
        rating: parentId ? null : rating,
        isApproved,
        isVerifiedPurchase: parentId ? null : isVerifiedPurchase
      };
      
      // Insert review
      const insertQuery = `
        INSERT INTO product_reviews 
        (id, product_id, user_id, parent_id, title, content, rating, is_approved, is_verified_purchase) 
        VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
        RETURNING *
      `;
      
      const result = await query(
        insertQuery,
        [
          reviewData.id,
          reviewData.productId,
          reviewData.userId,
          reviewData.parentId,
          reviewData.title,
          reviewData.content,
          reviewData.rating,
          reviewData.isApproved,
          reviewData.isVerifiedPurchase
        ]
      );
      
      // Get user info for the response
      const userResult = await query(
        'SELECT first_name, last_name FROM users WHERE id = $1',
        [userId]
      );
      
      const review = {
        ...result.rows[0],
        first_name: userResult.rows[0].first_name,
        last_name: userResult.rows[0].last_name,
        replies: []
      };
      
      res.status(201).json({
        message: isApproved 
          ? 'Review added successfully' 
          : 'Review submitted and awaiting approval',
        review
      });
    } catch (error) {
      next(error);
    }
  });
  
  // Check if user can review a product
  router.get('/:productId/can-review', async (req, res, next) => {
    try {
      const { productId } = req.params;
      const userId = req.user.id;
      const isAdmin = req.user.is_admin || false;
      
      // Check if user has already reviewed this product
      const existingReviewCheck = await query(`
        SELECT id FROM product_reviews
        WHERE product_id = $1 AND user_id = $2 AND parent_id IS NULL
        LIMIT 1
      `, [productId, userId]);
      
      if (existingReviewCheck.rows.length > 0) {
        return res.json({
          canReview: false,
          reason: 'You have already reviewed this product'
        });
      }
      
      // If user is admin, they can always review
      if (isAdmin) {
        return res.json({
          canReview: true,
          isAdmin: true
        });
      }
      
      // Check if user has purchased the product
      const purchaseCheck = await query(`
        SELECT o.id 
        FROM orders o
        JOIN order_items oi ON o.id = oi.order_id
        WHERE o.user_id = $1 
        AND oi.product_id = $2
        AND o.payment_completed = true
        LIMIT 1
      `, [userId, productId]);
      
      res.json({
        canReview: purchaseCheck.rows.length > 0,
        isPurchaser: purchaseCheck.rows.length > 0,
        isAdmin: false
      });
    } catch (error) {
      next(error);
    }
  });
  
  return router;
};