<?php

namespace App\Http\Controllers\Member;

use App\Http\Controllers\Controller;
use App\Models\Review;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\Product;
use App\Services\NotificationService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class ReviewController extends Controller
{
    /**
     * Liste des produits à noter (commandes livrées non encore notées)
     */
    public function index()
    {
        $user = auth()->user();
        
        // Récupérer les commandes livrées avec leurs items
        $deliveredOrders = Order::where('user_id', $user->id)
            ->where('status', 'delivered')
            ->with(['items.product'])
            ->orderBy('updated_at', 'desc')
            ->get();

        // Produits déjà notés
        $reviewedProductIds = Review::where('user_id', $user->id)->pluck('product_id')->toArray();

        // Produits à noter
        $productsToReview = collect();
        foreach ($deliveredOrders as $order) {
            foreach ($order->items as $item) {
                if ($item->product && !in_array($item->product_id, $reviewedProductIds)) {
                    $productsToReview->push((object)[
                        'product' => $item->product,
                        'order' => $order,
                        'quantity' => $item->quantity,
                        'ordered_at' => $order->created_at,
                        'delivered_at' => $order->updated_at,
                    ]);
                }
            }
        }
        
        // Mes avis soumis
        $myReviews = Review::where('user_id', $user->id)
            ->with('product')
            ->orderBy('created_at', 'desc')
            ->paginate(10);

        return view('member.reviews.index', compact('productsToReview', 'myReviews'));
    }

    /**
     * Formulaire de notation d'un produit
     */
    public function create(Request $request, $productId)
    {
        $user = auth()->user();
        $product = Product::findOrFail($productId);

        // Vérifier que l'utilisateur a bien acheté ce produit et la commande est livrée
        $hasOrderedProduct = Order::where('user_id', $user->id)
            ->where('status', 'delivered')
            ->whereHas('items', fn($q) => $q->where('product_id', $productId))
            ->exists();

        if (!$hasOrderedProduct) {
            return redirect()->route('member.reviews.index')
                ->with('error', 'Vous ne pouvez noter que les produits que vous avez achetés.');
        }

        // Vérifier s'il a déjà noté ce produit
        $existingReview = Review::where('user_id', $user->id)
            ->where('product_id', $productId)
            ->first();

        if ($existingReview) {
            return redirect()->route('member.reviews.edit', $existingReview->id);
        }

        // Récupérer l'ID de la commande livrée
        $order = Order::where('user_id', $user->id)
            ->where('status', 'delivered')
            ->whereHas('items', fn($q) => $q->where('product_id', $productId))
            ->first();

        return view('member.reviews.create', compact('product', 'order'));
    }

    /**
     * Enregistrer un nouvel avis
     */
    public function store(Request $request)
    {
        $user = auth()->user();

        $validator = Validator::make($request->all(), [
            'product_id' => 'required|exists:products,id',
            'order_id' => 'required|exists:orders,id',
            'rating' => 'required|integer|min:1|max:5',
            'title' => 'nullable|string|max:255',
            'comment' => 'required|string|min:10|max:1000',
        ], [
            'rating.required' => 'Veuillez sélectionner une note.',
            'comment.required' => 'Veuillez écrire votre avis.',
            'comment.min' => 'Votre avis doit contenir au moins 10 caractères.',
        ]);

        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput();
        }

        // Vérifier que l'utilisateur a bien commandé ce produit
        $order = Order::where('id', $request->order_id)
            ->where('user_id', $user->id)
            ->where('status', 'delivered')
            ->firstOrFail();

        // Vérifier que le produit est dans la commande
        $hasProduct = $order->items()->where('product_id', $request->product_id)->exists();
        if (!$hasProduct) {
            return back()->with('error', 'Ce produit n\'est pas dans cette commande.');
        }

        // Vérifier s'il n'a pas déjà noté
        $existingReview = Review::where('user_id', $user->id)
            ->where('product_id', $request->product_id)
            ->first();

        if ($existingReview) {
            return redirect()->route('member.reviews.index')
                ->with('error', 'Vous avez déjà noté ce produit.');
        }

        // Créer l'avis
        $review = Review::create([
            'user_id' => $user->id,
            'product_id' => $request->product_id,
            'order_id' => $request->order_id,
            'rating' => $request->rating,
            'title' => $request->title,
            'comment' => $request->comment,
            'is_verified_purchase' => true,
            'is_approved' => false, // En attente de modération
        ]);

        // Mettre à jour la note moyenne du produit
        $this->updateProductRating($request->product_id);

        // Notification d'avis soumis
        $product = Product::find($request->product_id);
        NotificationService::reviewSubmitted($user->id, $product->name ?? 'Produit');

        return redirect()->route('member.reviews.index')
            ->with('success', 'Merci pour votre avis ! Il sera visible après modération.');
    }

    /**
     * Modifier un avis existant
     */
    public function edit($id)
    {
        $review = Review::where('id', $id)
            ->where('user_id', auth()->id())
            ->with('product', 'order')
            ->firstOrFail();

        return view('member.reviews.edit', compact('review'));
    }

    /**
     * Mettre à jour un avis
     */
    public function update(Request $request, $id)
    {
        $review = Review::where('id', $id)
            ->where('user_id', auth()->id())
            ->firstOrFail();

        $validator = Validator::make($request->all(), [
            'rating' => 'required|integer|min:1|max:5',
            'title' => 'nullable|string|max:255',
            'comment' => 'required|string|min:10|max:1000',
        ]);

        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput();
        }

        $review->update([
            'rating' => $request->rating,
            'title' => $request->title,
            'comment' => $request->comment,
            'is_approved' => false, // Repasse en modération après modification
        ]);

        // Mettre à jour la note moyenne du produit
        $this->updateProductRating($review->product_id);

        return redirect()->route('member.reviews.index')
            ->with('success', 'Votre avis a été mis à jour.');
    }

    /**
     * Supprimer un avis
     */
    public function destroy($id)
    {
        $review = Review::where('id', $id)
            ->where('user_id', auth()->id())
            ->firstOrFail();

        $productId = $review->product_id;
        $review->delete();

        // Mettre à jour la note moyenne du produit
        $this->updateProductRating($productId);

        return back()->with('success', 'Votre avis a été supprimé.');
    }

    /**
     * Mettre à jour la note moyenne du produit
     */
    private function updateProductRating($productId)
    {
        $product = Product::find($productId);
        if (!$product) return;

        $reviews = Review::where('product_id', $productId)
            ->where('is_approved', true);

        $avgRating = $reviews->avg('rating') ?? 0;
        $reviewsCount = $reviews->count();

        $product->update([
            'rating' => round($avgRating, 2),
            'reviews_count' => $reviewsCount,
        ]);
    }
}
