<?php

namespace App\Http\Controllers\Api\Mobile;

use App\Http\Controllers\Controller;
use App\Models\Category;
use App\Models\Country;
use App\Models\DownloadLink;
use App\Models\Genre;
use App\Models\Movie;
use App\Models\MovieFile;
use App\Models\MovieLanguage;
use App\Models\Star;
use App\Models\User;
use App\Models\VideoQuality;
use App\Traits\Mobile\ApiResponseTrait;
use Carbon\Carbon;
use Illuminate\Http\Request;

class MovieController extends Controller
{
    use ApiResponseTrait;

    public function movies(Request $request)
    {

        $withMedia = function ($item) {
            $item->thumbnail = apiImageFromJson($item->thumbnail, 'original_image', 'movies');
            $item->poster = apiImageFromJson($item->poster, 'original_image', 'movies');

            return $item;
        };
        $type = $request->query('type');
        $perPage = min((int) $request->query('per_page', 20), 100);

        if (!$request->has('type') || is_null($type)) {
            // Case: type is not present OR is explicitly null
            $movies = Movie::where('status', 1)
                ->paginate($perPage)
                ->through($withMedia);
        } elseif ($type === 'newRelease') {
            // Case: type is 'newRelease'
            $movies = Movie::where('status', 1)
                ->orderBy('release', 'DESC')
                ->paginate($perPage)
                ->through($withMedia);
        } else {
            // Case: type is something else (like 'featured', 'paid', etc.)
            $movies = Movie::where('is_' . $type, 1)
                ->where('status', 1)
                ->paginate($perPage)
                ->through($withMedia);
        }
        $data = [
            'movies' => $movies,
            'filter' => [
                'categories' => Category::get(),
                'languages' => MovieLanguage::get(),
                'country' => Country::get(),
                'genre' => Genre::get(),
                'year' => range(1975, date('Y')),
                'sort' => [
                    'trending', //1
                    'featured', //2
                    'paid' //3
                ]
            ]
        ];
        return $this->responseWithSuccess($data, __('movies_retrieved_successfully'));
    }

    public function getActor($value)
    {
        $withMedia = function ($item) {
            $item->star_image = apiImageFromJson($item->star_image, 'original_image', 'stars');
            return $item;
        };

        $stars = [];
        foreach (json_decode($value) as $star) {
            $stars[] = $withMedia(Star::where('id', $star)->first());
        }
        return $stars;
    }

    public function movie_details(Request $request)
    {
        $user = User::find($request->user_id);
        $withMedia = function ($item) {
            $item->thumbnail = apiImageFromJson($item->thumbnail, 'original_image', 'movies');
            $item->poster = apiImageFromJson($item->poster, 'original_image', 'movies');
            $item->runtime = runtime($item->runtime);
            return $item;
        };
        $movie = Movie::where('id', $request->id)->first();

        if ($user) {
            $movie->is_favorite = $user ? $user->favoriteMovies()->where('movie_id', $movie->id)->exists() : false;
        }
        if (!$movie) {
            return $this->responseWithError(__('movie_not_found'), 400);
        }

        $latest = Movie::where('status', 1);

        $hours = (int) $movie->rental_duration;
        $days = intdiv($hours, 24);
        $remainingHours = $hours % 24;

        $validity = '';

        // If exactly 1 day (24 hours)
        if ($hours === 24) {
            $validity = '1 day';
        }
        // More than 1 day
        elseif ($hours > 24) {
            $validity .= $days . ' ' . ($days === 1 ? 'day' : 'days');

            if ($remainingHours > 0) {
                $validity .= ' ' . $remainingHours . ' ' . ($remainingHours === 1 ? 'hour' : 'hours');
            }
        }
        // Less than 1 day
        else {
            $validity = $hours . ' ' . ($hours === 1 ? 'hour' : 'hours');
        }

        $reviews = $movie->reviews()
            ->with('user')
            ->latest()
            ->get()
            ->map(function ($review) {
                $user = $review->user;

                // Only return specific user fields
                $test = $review->user = [
                    'review_id' => $review->id,
                    'user_id' => $user->id,
                    'name' => $user->first_name . ' ' . $user->last_name ?? '',
                    'review' => $review->review,
                    'rating' => $review->rating,
                    'image' => apiImageFromJson($user->image, 'original_image', 'users'),
                ];

                return $test;
            });

        if($user) {
            $is_rented = is_rented('movie', $request->id, $user->id) ? true : false;
        }

        $data = [
            'details' => $withMedia($movie),
            'server' => MovieFile::where('video_id', $movie->id)->get()->map(function ($file) {
                if ($file->file_source === 'local') {
                    $clientIp = request()->ip();
                    $isLocalhost = in_array($clientIp, ['127.0.0.1', '::1', ':8000']);

                    $path = $isLocalhost ? 'public/' . $file->file_url : $file->file_url;
                    $file->file_url = url($path);
                }
                return $file;
            }),
            'cast' => $this->getActor($movie->stars),
            'director' => $this->getActor($movie->director),
            'writer' => $this->getActor($movie->writer),
            'related_movie' => (clone $latest)
                ->where('video_type', $movie->video_type)
                ->get()
                ->transform($withMedia),
            'recommended_movie' => (clone $latest)
                ->where('is_recommended', 1)
                ->get()
                ->transform($withMedia),
            'playlist_ids' => $movie->playlists()->pluck('play_lists.id')->toArray(),
            'video_tags' => array_values(array_filter([
                VideoQuality::where('id', $movie->video_quality)->value('quality'),
                $movie->is_blockbuster ? 'Blockbuster' : null,
                get_genre($movie->genre, 0, 'name'),
            ])),
            'reviews' => $reviews ?? [],
            'rental' => [
                'price' => get_currency($movie->rental_price),
                'validity' => validity($movie->rental_duration),
                'expire_data' => Carbon::now()->copy()->addHours($movie->rental_duration)->format('Y-m-d H:i:s'),
            ],
            'download' => [
                'is_downloadable' => $movie->is_free ?? false,
                'details' => DownloadLink::where('downloadable_id', $movie->id)
                    ->where('downloadable_type', Movie::class)
                    ->where('status', 1)
                    ->get(),
            ],
            'is_rented' => $is_rented ?? false,
            'share_link' => route('movie.details', ['slug' => $movie->slug]),

        ];
        return $this->responseWithSuccess($data, __('movie_details_retrieved_successfully'));
    }

    public function movie_filter(Request $request)
    {

        $withMedia = function ($item) {
            $item->thumbnail = apiImageFromJson($item->thumbnail, 'original_image', 'movies');
            $item->poster = apiImageFromJson($item->poster, 'original_image', 'movies');
            return $item;
        };

        $query = Movie::query();

        // Search by title (partial match)
        if ($request->filled('string')) {
            $query->where('title', 'like', '%' . $request->string . '%');
        }

        // Filter by category_id
        if ($request->filled('category_id')) {
            $query->where('video_type', $request->category_id);
        }
        // Filter by category_id
        if ($request->filled('language_id')) {
            $query->whereJsonContains('language', $request->language_id);
        }
        // Filter by genre
        if ($request->filled('genre')) {
            $query->whereJsonContains('genre', (string) $request->genre);
        }
        // Filter by country
        if ($request->filled('country')) {
            $query->whereJsonContains('country', (string) $request->country);
        }
        // Filter by release date
        if ($request->filled('year')) {
            $query->whereYear('release', $request->year);
        }

        // Filter by year from created_at
        if ($request->filled('sort')) {
            if ($request->sort == 1) {
                $query->where('is_trending', 1);
            } elseif ($request->sort == 2) {
                $query->where('is_featured', 1);
            } elseif ($request->sort == 3) {
                $query->where('is_free', 1);
            }
        }

        $movies = $query->latest()->paginate(20)->through($withMedia);
        return $this->responseWithSuccess([
            'movies' => $movies,
            'filter' => [
                'categories' => Category::get(),
                'languages' => MovieLanguage::get(),
                'country' => Country::get(),
                'genre' => Genre::get(),
                'year' => range(1975, date('Y')),
                'sort' => [
                    'trending', //1
                    'featured', //2
                    'paid' //3
                ]
            ]
        ], __('movie_filter_results_retrieved_successfully'));
    }
}
