<?php

namespace App\Http\Controllers;

use App\Models\Review;
use App\Models\TravelPlan;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use App\Helpers\ApiResponse;
use Illuminate\Support\Facades\Storage;

class ReviewController extends Controller
{
    // POST /api/reviews
    public function store(Request $request)
    {

        $user = $request->user(); // authenticated user

        $data = $request->validate([
            'traveler_id' => ['required', 'integer'],
            'rating'           => ['required', 'integer', 'min:1', 'max:5'],
            'comment'          => ['nullable', 'string'],
        ]);

        // cannot review yourself
        if ((int)$data['traveler_id'] === (int)$user->id) {
            return ApiResponse::error(
                "You cannot review yourself.",
                422
            );
        }


        // prevent duplicate review for same trip & person
        $alreadyReviewed = Review::where('reviewed_user_id', $data['traveler_id'])
            ->where('reviewer_id', $user->id)
            ->exists();

        if ($alreadyReviewed) {
            return ApiResponse::error(
                "You have already reviewed this user for this trip.",
                422
            );
        }

        // create review in transaction and update rating
        DB::transaction(function () use ($data, $user, $request) {
            $review = Review::create([
                // 'travel_plan_id'   => $data['travel_plan_id'],
                'reviewer_id'      => $user->id,
                'reviewed_user_id' => $data['traveler_id'],
                'rating'           => $request->rating,
                'comment'          => $request->comment ?? null,
            ]);

            $this->recalculateUserRating($review->reviewedUser);
        });

        return ApiResponse::success(
            "Review added successfully.",
            $user,
            201
        );
    }

    // PATCH /api/reviews/{review}
    public function update(Request $request, Review $review)
    {
        $user = $request->user();

        if ($review->reviewer_id !== $user->id) {
            return response()->json([
                'message' => 'You can only edit your own reviews.',
            ], 403);
        }

        $data = $request->validate([
            'rating'  => ['sometimes', 'integer', 'min:1', 'max:5'],
            'comment' => ['nullable', 'string'],
        ]);

        $review->update($data);

        $this->recalculateUserRating($review->reviewedUser);

        return response()->json([
            'message' => 'Review updated successfully.',
        ]);
    }

    // DELETE /api/reviews/{review}
    public function destroy(Request $request, Review $review)
    {
        $user = $request->user();

        if ($review->reviewer_id !== $user->id) {
            return response()->json([
                'message' => 'You can only delete your own reviews.',
            ], 403);
        }

        $reviewedUser = $review->reviewedUser;

        $review->delete();

        $this->recalculateUserRating($reviewedUser);

        return response()->json([
            'message' => 'Review deleted successfully.',
        ]);
    }

    // GET /api/users/{user}/reviews
    public function reviewsForUser(User $user)
    {
        // 1. Load relations
        $user->load('reviewsReceived.reviewer');
    
        // 2. Map reviews
        $reviews = $user->reviewsReceived
            ->sortByDesc('created_at')
            ->map(function ($review) {
                return [
                    'id'         => $review->id,
                    'rating'     => $review->rating,
                    'comment'    => $review->comment,
                    'created_at' => $review->created_at->toDateTimeString(),
                    'reviewer'   => [
                        'id'    => $review->reviewer->id,
                        'name'  => $review->reviewer->name,
                        'image'=> isset($review->reviewer->image_url) && Storage::disk('public')->exists($review->reviewer->image_url) ? url("public/storage/{$review->reviewer->image_url}") : null,

                        // 'image' => $review->reviewer->image_url ?? null,
                    ],
                ];
            })
            ->values(); // reset array keys
            
            return ApiResponse::success(
                "Reviews fetched successfully.",
                [
                    'rating_avg'   => $user->rating_avg ?? 0,
                    'rating_count' => $user->rating_count ?? 0,
                    'reviews'      => $reviews,
                ]
            );
    }


    // helper: recalc rating_avg & rating_count on users table
    protected function recalculateUserRating(User $user): void
    {
        $stats = Review::where('reviewed_user_id', $user->id)
            ->selectRaw('COUNT(*) as count, AVG(rating) as avg_rating')
            ->first();

        $user->rating_count = $stats->count ?? 0;
        $user->rating_avg   = $stats->count > 0 ? round($stats->avg_rating, 2) : 0;
        $user->save();
    }
}
