<?php

namespace App\Http\Controllers;

use App\Models\Episode;
use App\Models\Playlist;
use App\Models\PlaylistEpisode;
use App\Services\PlaylistService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class PlaylistController extends Controller
{
    protected PlaylistService $playlistService;

    public function __construct(PlaylistService $playlistService)
    {
        $this->playlistService = $playlistService;
    }

    /**
     * Display the public playlists page.
     */
    public function index(): View
    {
        return view('playlist.index');
    }

    /**
     * Display public playlist.
     */
    public function show($playlist_id): View
    {
        if (! is_numeric($playlist_id)) {
            abort(404);
        }

        $playlist = Playlist::where('is_private', 0)->where('id', $playlist_id)->firstOrFail();

        return view('playlist.list', [
            'playlist' => $playlist,
        ]);
    }

    /**
     * Display the user's playlists page.
     */
    public function playlists(Request $request): View
    {
        $title = 'Delete Playlist!';
        $text = 'Are you sure you want to delete?';
        confirmDelete($title, $text);

        return view('profile.playlists', [
            'user' => $request->user(),
            'playlists' => $request->user()->playlists,
        ]);
    }

    /**
     * Display user's playlist.
     */
    public function showPlaylist(Request $request, $playlist_id): View
    {
        if (! is_numeric($playlist_id)) {
            abort(404);
        }

        $user = $request->user();

        $playlist = Playlist::where('user_id', $user->id)->where('id', $playlist_id)->firstOrFail();

        return view('playlist.list', [
            'playlist' => $playlist,
        ]);
    }

    /**
     * Create user playlist (Form).
     */
    public function createPlaylist(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'name' => 'required|max:30',
        ]);

        $playlist = new Playlist;
        $playlist->user_id = $request->user()->id;
        $playlist->name = $request->input('name');
        $playlist->is_private = $request->input('visiblity') === 'private';
        $playlist->save();

        return to_route('profile.playlists');
    }

    /**
     * Update user playlist.
     */
    public function updatePlaylist(Request $request, $playlist_id): RedirectResponse
    {
        if (! is_numeric($playlist_id)) {
            abort(404);
        }

        $validated = $request->validate([
            'name' => 'required|max:30',
            'is_private' => 'required|boolean',
        ]);

        $user = $request->user();

        $playlist = Playlist::where('user_id', $user->id)
            ->where('id', $playlist_id)
            ->firstOrFail();

        $playlist->update([
            'name' => $request->input('name'),
            'is_private' => $request->input('is_private'),
        ]);

        return back()->with('status', 'playlist-updated');
    }

    /**
     * Delete user playlist.
     */
    public function deletePlaylist(Request $request, $playlist_id): RedirectResponse
    {
        if (! is_numeric($playlist_id)) {
            abort(404);
        }

        $user = $request->user();

        $playlist = Playlist::where('user_id', $user->id)
            ->where('id', $playlist_id)
            ->firstOrFail();

        $playlist->delete();

        return to_route('profile.playlists');
    }

    /**
     * Delete episode from playlist.
     */
    public function deleteEpisodeFromPlaylist(Request $request): JsonResponse
    {
        if (! is_numeric($request->input('playlist')) || ! is_numeric($request->input('episode'))) {
            return response()->json([
                'message' => 'not-numeric',
                'user' => $request->user(),
            ], 404);
        }

        $playlist = Playlist::where('user_id', $request->user()->id)
            ->where('id', (int) $request->input('playlist'))
            ->firstOrFail();

        PlaylistEpisode::where('playlist_id', $playlist->id)
            ->where('episode_id', (int) $request->input('episode'))
            ->delete();

        $this->playlistService->reorderPositions($playlist);

        return response()->json([
            'message' => 'success',
            'user' => $request->user(),
        ], 200);
    }

    /**
     * Add to user playlist (API).
     */
    public function addPlaylistApi(Request $request): JsonResponse
    {
        $user = $request->user();

        $validated = $request->validate([
            'playlist' => 'required|max:30',
            'episode_id' => 'required',
        ]);

        $playlist = Playlist::where('user_id', $user->id)->where('id', $request->input('playlist'))->firstOrFail();
        $episode = Episode::where('id', $request->input('episode_id'))->firstOrFail();

        // Check if already in playlist
        $exists = PlaylistEpisode::where('playlist_id', $playlist->id)->where('episode_id', $episode->id)->exists();
        if ($exists) {
            return response()->json([
                'message' => 'already-added',
            ], 200);
        }

        // Position of entry
        $position = $playlist->episodes->count() + 1;

        PlaylistEpisode::create([
            'playlist_id' => $playlist->id,
            'episode_id' => $episode->id,
            'position' => $position,
        ]);

        return response()->json([
            'message' => 'success',
        ], 200);
    }

    /**
     * Create user playlist (API).
     */
    public function createPlaylistApi(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'name' => 'required|max:30',
        ]);

        $playlist = new Playlist;
        $playlist->user_id = $request->user()->id;
        $playlist->name = $request->input('name');
        $playlist->is_private = $request->input('visiblity') === 'private';
        $playlist->save();

        return response()->json([
            'message' => 'success',
            'playlist_id' => $playlist->id,
        ], 200);
    }
}
