<?php

namespace App\Http\Controllers;

use App\Models\Order;
use App\Models\Product;
use App\Models\Review;
use App\Models\ReviewImage;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class ReviewController extends Controller
{
    /**
     * Show review form for authenticated users
     */
    public function create(Order $order)
    {
        // Authorization check
        if ($order->user_id !== auth()->id()) {
            abort(403, 'Unauthorized');
        }

        // Check if order completed
        if ($order->status !== 'completed') {
            return redirect()->route('orders.show', $order)
                ->with('error', 'Order belum selesai!');
        }

        // Check if already reviewed
        if ($order->hasBeenReviewed()) {
            return redirect()->route('orders.show', $order)
                ->with('error', 'Anda sudah memberikan review untuk order ini.');
        }

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

    /**
     * Show review form via token (for guest users)
     */
    public function createByToken($token)
    {
        $order = Order::where('review_token', $token)
            ->where('status', 'completed')
            ->firstOrFail();

        // Check if already reviewed
        if ($order->hasBeenReviewed()) {
            return view('reviews.already-reviewed', compact('order'));
        }

        return view('reviews.create-guest', compact('order'));
    }

    /**
     * Store review (authenticated)
     */
    public function store(Request $request, Order $order)
    {
        // Validate
        $validated = $request->validate([
            'rating' => 'required|integer|min:1|max:5',
            'comment' => 'nullable|string|max:1000',
            'reviewer_name' => 'nullable|string|max:100',
            'images.*' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
        ]);

        // Authorization
if ($order->user_id !== auth()->id()) {           
     abort(403);
        }

        // Check if order completed
        if ($order->status !== 'completed') {
            return back()->with('error', 'Order belum selesai!');
        }

        // Check duplicate
        if ($order->hasBeenReviewed()) {
            return back()->with('error', 'Anda sudah memberikan review!');
        }

        return $this->storeReview($order, $validated, auth()->user());
    }

    /**
     * Store review via token (guest)
     */
    public function storeByToken(Request $request, $token)
    {
        $order = Order::where('review_token', $token)
            ->where('status', 'completed')
            ->firstOrFail();

        // Check if already reviewed
        if ($order->hasBeenReviewed()) {
            return redirect()->route('reviews.already-reviewed')
                ->with('error', 'Review sudah pernah diberikan untuk order ini.');
        }

        $validated = $request->validate([
            'rating' => 'required|integer|min:1|max:5',
            'comment' => 'nullable|string|max:1000',
            'reviewer_name' => 'required|string|max:100',
            'images.*' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
        ]);

        return $this->storeReview($order, $validated, null, $order->guest_email);
    }

    /**
     * Common method to store review
     */
    private function storeReview(Order $order, array $validated, $user = null, $email = null)
    {
        DB::beginTransaction();

        try {
            // Create review
            $review = Review::create([
                'user_id' => $user ? $user->id : null,
                'order_id' => $order->id,
                'product_id' => $order->product_id,
                'rating' => $validated['rating'],
                'comment' => $validated['comment'] ?? null,
                'reviewer_name' => $validated['reviewer_name'] ?? ($user ? $user->name : $order->guest_name),
                'reviewer_email' => $email,
                'is_verified_purchase' => true,
                'status' => 'approved',
            ]);

            // Handle images
            if (request()->hasFile('images')) {
                foreach (request()->file('images') as $index => $image) {
                    $path = $image->store('reviews', 'public');

                    ReviewImage::create([
                        'review_id' => $review->id,
                        'image_path' => $path,
                        'order' => $index,
                    ]);
                }
            }

            // Mark order as reviewed
            $order->update(['reviewed_at' => now()]);

            // Update product rating cache
            $order->product->updateRatingCache();

            DB::commit();

            if ($user) {
                return redirect()->route('orders.show', $order)
                    ->with('success', 'Terima kasih atas review Anda! 🌟');
            } else {
                return view('reviews.thankyou', compact('order', 'review'));
            }

        } catch (\Exception $e) {
            DB::rollBack();
            
            \Log::error('Review creation failed', [
                'order_id' => $order->id,
                'error' => $e->getMessage(),
            ]);

            return back()->with('error', 'Terjadi kesalahan. Silakan coba lagi.');
        }
    }

    /**
     * Show all reviews for a product
     */
    public function index(Request $request, $productSlug)
    {
        $product = Product::where('slug', $productSlug)->firstOrFail();

        $query = $product->approvedReviews()
            ->with(['user', 'images', 'reply']);

        // Filter by rating
        if ($request->has('rating') && $request->rating > 0) {
            $query->where('rating', $request->rating);
        }

        // Filter verified only
        if ($request->has('verified') && $request->verified) {
            $query->where('is_verified_purchase', true);
        }

        // Filter with images only
        if ($request->has('with_images') && $request->with_images) {
            $query->has('images');
        }

        // Filter with comments only
        if ($request->has('with_comments') && $request->with_comments) {
            $query->whereNotNull('comment')->where('comment', '!=', '');
        }

        // Sort
        $sortBy = $request->get('sort', 'recent');
        switch ($sortBy) {
            case 'helpful':
                $query->orderBy('helpful_count', 'desc');
                break;
            case 'rating_high':
                $query->orderBy('rating', 'desc')->latest();
                break;
            case 'rating_low':
                $query->orderBy('rating', 'asc')->latest();
                break;
            case 'recent':
            default:
                $query->latest();
                break;
        }

        $reviews = $query->paginate(10)->appends($request->query());

        // Get rating breakdown
        $ratingBreakdown = $product->getRatingBreakdown();

        return view('reviews.index', compact('product', 'reviews', 'ratingBreakdown'));
    }

    /**
     * Edit review
     */
    public function edit(Review $review)
    {
        // Authorization
        if ($review->user_id !== auth()->id()) {
            abort(403);
        }

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

    /**
     * Update review
     */
    public function update(Request $request, Review $review)
    {
        // Authorization
        if ($review->user_id !== auth()->id()) {
            abort(403);
        }

        $validated = $request->validate([
            'rating' => 'required|integer|min:1|max:5',
            'comment' => 'nullable|string|max:1000',
            'reviewer_name' => 'nullable|string|max:100',
        ]);

        $review->update([
            'rating' => $validated['rating'],
            'comment' => $validated['comment'],
            'reviewer_name' => $validated['reviewer_name'] ?? auth()->user()->name,
        ]);

        // Update product rating cache
        $review->product->updateRatingCache();

        return redirect()->route('orders.show', $review->order_id)
            ->with('success', 'Review berhasil diupdate!');
    }

    /**
     * Delete review
     */
    public function destroy(Review $review)
    {
        // Authorization
        if ($review->user_id !== auth()->id()) {
            abort(403);
        }

        $productId = $review->product_id;

        $review->delete();

        // Update product rating cache
        Product::find($productId)->updateRatingCache();

        return back()->with('success', 'Review berhasil dihapus.');
    }
}