<?php

namespace App\Http\Controllers\Api\Mobile;

use App\Http\Controllers\Controller;
use App\Models\Episode;
use App\Models\LiveTv;
use App\Models\Movie;
use App\Models\WatchHistory;
use Illuminate\Http\Request;
use App\Traits\Mobile\ApiResponseTrait;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\Validator;

class WatchHistoryController extends Controller
{

    use ApiResponseTrait;

    public function watchHistory(Request $request)
    {
        $histories = WatchHistory::where('user_id', $request->user_id)->paginate(10);

        if (count($histories) > 0) {
            // Transform each history item to include formatted time
            $transformedHistories = $histories->getCollection()->map(function ($history) {
                // Initialize watchable data
                $watchableData = null;

                // Fetch watchable details based on type (movie/series)
                if ($history->watchable_type === 'movie') {
                    $watchable = Movie::find($history->watchable_id);
                    if ($watchable) {
                        $watchableData = [
                            'title' => $watchable->title,
                            'thumbnail' => apiImageFromJson($watchable->thumbnail, 'original_image', 'movies')
                        ];
                    }
                } elseif ($history->watchable_type === 'episode') {
                    $watchable = Episode::find($history->watchable_id);
                    if ($watchable) {
                        $watchableData = [
                            'title' => $watchable->episode_name,
                            'thumbnail' => apiImageFromJson($watchable->poster, 'original_image', 'episodes')
                        ];
                    } 
                } elseif ($history->watchable_type === 'tv_channel') {
                    $watchable = LiveTv::find($history->watchable_id);
                    if ($watchable) {
                        $watchableData = [
                            'title' => $watchable->tv_name,
                            'thumbnail' => apiImageFromJson($watchable->thumbnail, 'original_image', '')
                        ];
                    }
                }

                return [
                    'id' => $history->id,
                    'user_id' => $history->user_id,
                    'watchable_type' => $history->watchable_type,
                    'watchable_id' => $history->watchable_id,
                    'watchable_details' => $watchableData, // Include watchable details
                    'duration' => round($history->duration / 60, 2) . ' mins',
                    'watched_seconds' => round($history->watched_seconds / 60, 2) . ' mins',
                    'watch_count' => $history->watch_count,
                    'completion_percentage' => $history->completion_percentage . '%',
                    'last_watched_at' => $history->last_watched_at,
                    'created_at' => $history->created_at,
                    'updated_at' => $history->updated_at,
                ];
            });

            // Replace the collection with the transformed data
            $histories->setCollection($transformedHistories);

            $data = [
                'histories' => $histories
            ];
            return $this->responseWithSuccess($data, __('watch_history_retrieved_successfully'));
        }

        return $this->responseWithError(__('history_is_empty'), 404);
    }

    public function watchHistoryStore(Request $request)
    {
        // Check authentication
        if (!$request->user_id) {
            return $this->responseWithError(__('unauthorized'), 401);
        }

        // Validate input
        $validator = Validator::make($request->all(), [
            'watchable_type' => 'required|string|in:movie,episode,tv_channel',
            'watchable_id' => [
                'required',
                'integer',
                function ($attribute, $value, $fail) use ($request) {
                    $model = null;

                    switch ($request->watchable_type) {
                        case 'movie':
                            $model = Movie::class;
                            break;
                        case 'episode':
                            $model = Episode::class;
                            break;
                        case 'tv_channel':
                            $model = LiveTv::class;
                            break;
                    }

                    if ($model && !$model::where('id', $value)->exists()) {
                        $fail("The selected $request->watchable_type does not exist.");
                    }
                }
            ],
            'duration' => 'required|integer|min:1',
            'watched_seconds' => 'required|integer|min:0',
        ]);

        if ($validator->fails()) {
            return $this->responseWithError($validator->errors(), 422);
        }

        // Ensure watched seconds doesn't exceed duration
        $watchedSeconds = min($request->watched_seconds, $request->duration);
        try {
            $watchHistory = WatchHistory::firstOrNew([
                'user_id' => $request->user_id,
                'watchable_type' => $request->watchable_type,
                'watchable_id' => $request->watchable_id,
            ]);

            // Only update if the new position is further than previous
            if ($watchedSeconds > ($watchHistory->watched_seconds ?? 0)) {
                $watchHistory->watched_seconds = $watchedSeconds;
                $watchHistory->duration = $request->duration;
                $watchHistory->completion_percentage = min(
                    100,
                    round(($watchedSeconds / $request->duration) * 100, 2)
                );
                $watchHistory->last_watched_at = now();
                $watchHistory->save();

                return $this->responseWithSuccess([
                    'history' => $watchHistory,
                    'formatted_times' => [
                        'duration_minutes' => round($watchHistory->duration / 60, 2),
                        'watched_minutes' => round($watchHistory->watched_seconds / 60, 2),
                    ]
                ], __('watch_history_added_successfully'));
            }

            return $this->responseWithSuccess(null, __('no_update_needed'));
        } catch (\Exception $e) {
            return $this->responseWithError(__('failed_to_update_watch_history') . $e->getMessage(), 500);
        }
    }
}
