<?php

namespace App\Http\Controllers;

use App\Models\Game;
use App\Models\GameList;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class GameListController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @param   string    $username
     * @return \Illuminate\Http\Response
     */
    public function index($username = null)
    {
        // If username is null, $user is the currently logged in user.
        if ($username === null) {
            $user = auth()->user();
        } else { // Otherwise, $user is the user with the specified username.
            $user = User::where('username', $username)->firstOrFail();
        }

        // Direct the user to the games list page.
        return view('pages.game-lists.index', compact('user'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @param   int    $gameId
     * @return \Illuminate\Http\Response
     */
    public function create($gameId)
    {
        // Make sure $gameId is numeric.
        if (is_numeric($gameId)) {
            return view('pages.game-lists.create', ['gameId' => $gameId]);
        } else { // Else go to the home page.
            return redirect()->route('index');
        }
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        // Validate the data from the request.
        $inputs = $this->validate($request, [
            'name' => [
                'string',
                'max:128',
                'nullable'
            ],
            'ownership' => [
                'numeric',
                'nullable',
                Rule::in([1, 2, 3, 4])
            ],
            'status' => [
                'numeric',
                Rule::in([1, 2, 3, 4, 5, 6])
            ],
            'rating' => [
                'numeric',
                'nullable',
                Rule::in([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
            ],
            'priority' => [
                Rule::in(['Low', 'Medium', 'High']),
                'string',
                'max:6',
                'nullable',
            ],
            'difficulty' => [
                'string',
                'nullable',
                Rule::in(['Easy', 'Medium', 'Hard', 'Extremely Hard'])
            ],
            'hoursPlayed' => [
                'numeric',
                'nullable',
                Rule::in([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
            ],
            'start_date' => 'date_format:Y-m-d|after:1970-01-01 00:00:00|nullable',
            'finish_date' => 'date_format:Y-m-d|after:1970-01-01 00:00:00|nullable',
            'replayValue' => [
                'numeric',
                'nullable',
                Rule::in([1, 2, 3, 4, 5])
            ],
            'notes' => 'string|nullable'
        ]);

        // Fetch a Game Model.
        $game = Game::whereId($request->input('gameId'))->first();

        // Fetch the name if none was selected.
        if (!$request->input('name')) {
            $inputs['name'] = $game->name;
        }

        // Set $input['game_id'].
        $inputs['game_id'] = $game->id;

        // Set $inputs['platform_id'].
        $inputs['platform_id'] = Game::whereId($game->id)->value('platform_id');

        // Set the value of replayValue.
        if (!$request->input('replayValue')) {
            $inputs['replayValue'] = null;
        }

        // Set the value of isReplaying.
        if ($request->input('isReplaying') == 1) {
            $inputs['isReplaying'] = 'Y';
        } else {
            $inputs['isReplaying'] = 'N';
        }

        // Save the data to the database.
        $result = auth()->user()->gameList()->create($inputs);

        // If adding the game was successful go to the users list.
        if ($result->exists) {
            return redirect('/list')->with('create_success', str_replace('"', '', json_encode($inputs['name'])));
        } else { // If the addition failed, go back.
            return back();
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\GameList  $gameList
     * @return \Illuminate\Http\Response
     */
    public function show(GameList $gameList)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\GameList  $gameList
     * @return \Illuminate\Http\Response
     */
    public function edit(GameList $gameList)
    {
        // Direct the user to the edit page.
        return view('pages.game-lists.edit', compact('gameList'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\GameList  $gameList
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, GameList $gameList)
    {
        // Validate the data from the request.
        $inputs = $this->validate($request, [
            'name' => 'string|max:128|nullable',
            'ownership' => [
                'numeric',
                'nullable',
                Rule::in([1, 2, 3, 4])
            ],
            'status' => [
                'numeric',
                Rule::in([1, 2, 3, 4, 5, 6])
            ],
            'rating' => [
                'numeric',
                'nullable',
                Rule::in([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
            ],
            'priority' => [
                Rule::in(['Low', 'Medium', 'High']),
                'string',
                'max:6',
                'nullable',
            ],
            'difficulty' => [
                'string',
                'nullable',
                Rule::in(['Easy', 'Medium', 'Hard', 'Extremely Hard'])
            ],
            'hoursPlayed' => [
                'numeric',
                'nullable',
                Rule::in([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
            ],
            'start_date' => 'date_format:Y-m-d|after:1970-01-01 00:00:00|nullable',
            'finish_date' => 'date_format:Y-m-d|after:1970-01-01 00:00:00|nullable',
            'replayValue' => [
                'numeric',
                'nullable',
                Rule::in([1, 2, 3, 4, 5])
            ],
            'notes' => 'string|nullable'
        ]);

        // Fetch a Game Model.
        $game = Game::whereId($gameList->game_id)->first();

        // Fetch the name if none was selected.
        if (!$request->input('name')) {
            $inputs['name'] = $game->name;
        }

        // Set $inputs['platform_id'].
        $inputs['platform_id'] = $game->platform_id;

        // Set the value of replayValue.
        if (!$request->input('replayValue')) {
            $inputs['replayValue'] = null;
        }

        // Set the value of isReplaying.
        if ($request->input('isReplaying') == 1) {
            $inputs['isReplaying'] = 'Y';
        } else {
            $inputs['isReplaying'] = 'N';
        }

        // Set the values of the gameList object to the updates values.
        $gameList['name'] = $inputs['name'];
        $gameList['ownership'] = $inputs['ownership'];
        $gameList['status'] = $inputs['status'];
        $gameList['rating'] = $inputs['rating'];
        $gameList['priority'] = $inputs['priority'];
        $gameList['difficulty'] = $inputs['difficulty'];
        $gameList['hours_played'] = $inputs['hoursPlayed'];
        $gameList['start_date'] = $inputs['start_date'];
        $gameList['finish_date'] = $inputs['finish_date'];
        $gameList['replay_value'] = $inputs['replayValue'];
        $gameList['notes'] = $inputs['notes'];
        $gameList['is_replaying'] = $inputs['isReplaying'];

        // Ensure the user has permission to update this game list entry.
        $this->authorize('update', $gameList);

        // Save the data to the database.
        $result = $gameList->save();

        // If the update was successful go back to the edit page with a success message.
        if ($result === true) {
            return redirect('/list/edit/' . $gameList->id)->with('edit_success', '1');
        } else { // If the update failed, go back.
            return back();
        }
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\GameList  $gameList
     * @return \Illuminate\Http\Response
     */
    public function destroy(GameList $gameList)
    {
        // Check to ensure this user has permission to delete this game list entry.
        $this->authorize('delete', $gameList);

        // Soft delete the entry within the database.
        $gameList->delete();

        // Go back to the users game list.
        return redirect('/list')->with('delete_success', str_replace('"', '', json_encode($gameList->name)));
    }
}
