<?php
/**
 * ============================================================
 * REVIEW SERVICE
 * ============================================================
 * Handles product reviews with admin approval
 */

class ReviewService {
    
    /**
     * Submit a review
     * @param int $productId
     * @param int $userId
     * @param int $rating
     * @param string|null $title
     * @param string|null $text
     * @param int|null $orderId
     * @return array
     */
    public static function submit(
        int $productId,
        int $userId,
        int $rating,
        ?string $title = null,
        ?string $text = null,
        ?int $orderId = null
    ): array {
        // Validate rating
        if ($rating < 1 || $rating > 5) {
            return ['success' => false, 'message' => 'রেটিং ১-৫ এর মধ্যে হতে হবে'];
        }
        
        // Check if product exists
        $product = Database::fetchColumn("SELECT id FROM products WHERE id = ?", [$productId]);
        if (!$product) {
            return ['success' => false, 'message' => 'পণ্য পাওয়া যায়নি'];
        }
        
        // Check if user already reviewed this product
        $exists = Database::fetchColumn(
            "SELECT id FROM product_reviews WHERE product_id = ? AND user_id = ?",
            [$productId, $userId]
        );
        
        if ($exists) {
            return ['success' => false, 'message' => 'আপনি ইতিমধ্যে এই পণ্যের রিভিউ দিয়েছেন'];
        }
        
        // Insert review (pending approval)
        Database::insert(
            "INSERT INTO product_reviews (product_id, user_id, order_id, rating, review_title, review_text, is_approved)
             VALUES (?, ?, ?, ?, ?, ?, 0)",
            [$productId, $userId, $orderId, $rating, $title, $text]
        );
        
        return [
            'success' => true,
            'message' => 'রিভিউ জমা হয়েছে। অ্যাডমিন অনুমোদনের পর প্রকাশ হবে।'
        ];
    }
    
    /**
     * Approve review (admin)
     * @param int $reviewId
     * @param int $adminId
     * @return array
     */
    public static function approve(int $reviewId, int $adminId): array {
        $review = Database::fetchOne("SELECT * FROM product_reviews WHERE id = ?", [$reviewId]);
        
        if (!$review) {
            return ['success' => false, 'message' => 'রিভিউ পাওয়া যায়নি'];
        }
        
        try {
            Database::beginTransaction();
            
            // Approve review
            Database::execute(
                "UPDATE product_reviews SET is_approved = 1, approved_by_admin_id = ?, approved_at = NOW() WHERE id = ?",
                [$adminId, $reviewId]
            );
            
            // Update product average rating
            self::updateProductRating($review['product_id']);
            
            Database::commit();
            
            return ['success' => true, 'message' => 'রিভিউ অনুমোদিত হয়েছে'];
            
        } catch (Exception $e) {
            Database::rollback();
            return ['success' => false, 'message' => 'রিভিউ অনুমোদনে সমস্যা হয়েছে'];
        }
    }
    
    /**
     * Reject/delete review (admin)
     * @param int $reviewId
     * @return array
     */
    public static function reject(int $reviewId): array {
        $review = Database::fetchOne("SELECT * FROM product_reviews WHERE id = ?", [$reviewId]);
        
        if (!$review) {
            return ['success' => false, 'message' => 'রিভিউ পাওয়া যায়নি'];
        }
        
        Database::execute("DELETE FROM product_reviews WHERE id = ?", [$reviewId]);
        
        // Update product rating if was approved
        if ($review['is_approved']) {
            self::updateProductRating($review['product_id']);
        }
        
        return ['success' => true, 'message' => 'রিভিউ মুছে ফেলা হয়েছে'];
    }
    
    /**
     * Update product average rating
     * @param int $productId
     */
    private static function updateProductRating(int $productId): void {
        $stats = Database::fetchOne(
            "SELECT AVG(rating) as avg_rating, COUNT(*) as review_count 
             FROM product_reviews 
             WHERE product_id = ? AND is_approved = 1",
            [$productId]
        );
        
        Database::execute(
            "UPDATE products SET avg_rating = ?, review_count = ? WHERE id = ?",
            [
                round($stats['avg_rating'] ?? 0, 1),
                $stats['review_count'] ?? 0,
                $productId
            ]
        );
    }
    
    /**
     * Get approved reviews for product
     * @param int $productId
     * @param int $limit
     * @param int $offset
     * @return array
     */
    public static function getByProduct(int $productId, int $limit = 10, int $offset = 0): array {
        return Database::fetchAll(
            "SELECT r.*, u.full_name as user_name
             FROM product_reviews r
             JOIN users u ON r.user_id = u.id
             WHERE r.product_id = ? AND r.is_approved = 1
             ORDER BY r.created_at DESC
             LIMIT ? OFFSET ?",
            [$productId, $limit, $offset]
        );
    }
    
    /**
     * Get all reviews for admin
     * @param array $filters
     * @param int $limit
     * @param int $offset
     * @return array
     */
    public static function getAllAdmin(array $filters = [], int $limit = 20, int $offset = 0): array {
        $where = "1=1";
        $params = [];
        
        if (isset($filters['is_approved'])) {
            $where .= " AND r.is_approved = ?";
            $params[] = $filters['is_approved'];
        }
        
        $params[] = $limit;
        $params[] = $offset;
        
        return Database::fetchAll(
            "SELECT r.*, u.full_name as user_name, p.name as product_name
             FROM product_reviews r
             JOIN users u ON r.user_id = u.id
             JOIN products p ON r.product_id = p.id
             WHERE {$where}
             ORDER BY r.created_at DESC
             LIMIT ? OFFSET ?",
            $params
        );
    }
    
    /**
     * Get pending review count (admin)
     * @return int
     */
    public static function getPendingCount(): int {
        return (int)Database::fetchColumn(
            "SELECT COUNT(*) FROM product_reviews WHERE is_approved = 0"
        );
    }
}
