<?php

namespace App\Http\Controllers\Api\Mobile;

use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\ReviewRequest;
use App\Models\Blog;
use App\Models\Movie;
use App\Models\Rent;
use App\Models\RentalHistory;
use App\Models\Review;
use App\Models\ReviewLikes;
use App\Models\TvShow;
use App\Models\User;
use Exception;
use App\Repositories\Interfaces\Admin\ReviewInterface;
use App\Traits\Mobile\ApiResponseTrait;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Laravel\Sanctum\PersonalAccessToken;

class ReviewController extends Controller
{
    protected $reviewRepo;

    use ApiResponseTrait;

    public function __construct(ReviewInterface $reviewRepo)
    {
        $this->reviewRepo = $reviewRepo;
    }

    public function ratingStore(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'rating' => 'required|numeric|min:1|max:5',
            'review' => 'required|string',
            'reviewable_type' => 'required|string|in:movie,tvshow,blog',
            'reviewable_id' => 'required|numeric',
        ]);

        if ($validator->fails()) {
            return $this->responseWithValidation($validator->errors(), 422);
        }
        try {
            $modelMap = [
                'movie' => Movie::class,
                'tvshow' => TvShow::class,
                'blog' => Blog::class,
            ];

            $type = $request['reviewable_type'];
            $modelClass = $modelMap[$type];
            $reviewable = $modelClass::findOrFail($request['reviewable_id']);

            $data = $this->reviewRepo->createFor($reviewable, $request->all());

            return $this->responseWithSuccess($data, __('rating_created_successfully'));
        } catch (Exception $e) {
            return $this->responseWithError($e->getMessage(), 500);
        }
    }



    public function LikeToggle(Request $request)
    {
        try {
            $user = auth()->user();

            if (!$user) {
                return $this->responseWithError(
                    __('user_not_found'),
                    500
                );
            }

            $review = Review::find($request->review_id);

            if (!$review) {
                return $this->responseWithError(
                    __('review_not_found'),
                    404
                );
            }

            $like = $review->likes()->where('user_id', $user->id)->first();

            if ($like) {
                $like->delete();
                $liked = false;
            } else {
                $review->likes()->create(['user_id' => $user->id]);
                $liked = true;
            }

            $data = [
                'message' => $liked ? __('liked_successfully') : __('unliked_successfully'),
                'liked' => $liked,
                'count' => $review->likes()->count(),
            ];
            return $this->responseWithSuccess($data, $data['message']);
        } catch (Exception $e) {
            return $this->responseWithError(
                $e->getMessage(),
                500
            );
        }
    }
    public function reviewList(Request $request)
    {
        try {
            $userId = null;

            if ($request->bearerToken()) {
                $accessToken = PersonalAccessToken::findToken($request->bearerToken());
                if ($accessToken && $accessToken->tokenable) {
                    $userId = $accessToken->tokenable->id;
                }
            }
            $types = [
                'movie' => Movie::class,
                'tvshow' => TvShow::class,
                'blog' => Blog::class,
            ];

            $typeKey = $request->reviewable_type;

            if (!isset($types[$typeKey])) {
                return $this->responseWithError(__('invalid_reviewable_type'), 422);
            }

            $reviews = Review::with('user')
                ->where('reviewable_id', $request->reviewable_id)
                ->where('reviewable_type', $types[$typeKey])
                ->orderBy('created_at', 'desc')
                ->get()
                ->transform(function ($item) use ($userId) {
                    $likes = ReviewLikes::where('review_id', $item->id)->get();

                    return [
                        'id' => $item->id,
                        'review' => $item->review,
                        'rating' => $item->rating ?? null,
                        'created_at' => date('d M Y', strtotime($item->created_at)),
                        'updated_at' => date('d M Y', strtotime($item->updated_at)),
                        'user' => $item->user ? [
                            'id' => $item->user->id,
                            'user_name' => trim($item->user->first_name . ' ' . $item->user->last_name),
                            'email' => $item->user->email,
                            'profile_image' => apiImage(optional(json_decode($item->user->image))->original_image, 'users'),
                        ] : null,
                        'total_likes' => $likes->count(),
                        'is_liked' => $userId ? $likes->contains('user_id', $userId) : false,
                    ];
                });

            return $this->responseWithSuccess(
                ['reviews' => $reviews],
                __('review_list_retrieved_successfully')
            );
        } catch (Exception $e) {
            Log::error('Review list retrieval failed', ['error' => $e->getMessage()]);
            return $this->responseWithError(
                __('review_list_retrieval_failed'),
                500
            );
        }
    }

    public function rentVideoList(Request $request)
    {
        try {
            $rents = RentalHistory::where('user_id', $request->user_id)->get();
            if ($rents->isEmpty()) {
                return $this->responseWithError(
                    __('no_rented_videos_found'),
                    404
                );
            }
            return $this->responseWithSuccess($rents, __('rent_retrieved_successfully'));
        } catch (Exception $e) {
            // Log::error('Review store failed', ['error' => $e->getMessage()]);
            return $this->responseWithError(
                $e->getMessage(),
                500
            );
        }
    }
}
