<?php

namespace App\Http\Controllers;

use App\Models\Game;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class GameController extends Controller
{
    const GHOST_ID = 1;

    public function index(Request $request)
    {
        $this->authorize('viewAny', Game::class);
        
        $user = Auth::user();
        $query = Game::query()->with(["winner", "player1", "player2"]);
        
        // Filter games based on user type
        if ($user->type !== 'A') {
            // Players can only see games they participate in
            $query->where(function ($q) use ($user) {
                $q->where('player1_user_id', $user->id)
                  ->orWhere('player2_user_id', $user->id);
            });
        }
        // Admins see all games (no filter needed)

        if ($request->has("type") && in_array($request->type, ["3", "9"])) {
            $query->where("type", $request->type);
        }

        if (
            $request->has("status") &&
            in_array($request->status, [
                "Pending",
                "Playing",
                "Ended",
                "Interrupted",
            ])
        ) {
            $query->where("status", $request->status);
        }

         if ($request->has("sort_direction") && in_array($request->sort_direction, ["asc", "desc"])) {
            $query->orderBy("began_at", $request->sort_direction);
        }else{
            $query->orderBy("began_at", "desc");
        }

        return response()->json($query->paginate(15));
    }

    public function store(Request $request)
    {
        $this->authorize('create', Game::class);
        
        $validated = $request->validate([
            "type" => "required|in:3,9",
        ]);

        $user = Auth::user();

        $activeGame = Game::where(function ($q) use ($user) {
            $q->where("player1_user_id", $user->id)
              ->orWhere("player2_user_id", $user->id);
        })
        ->whereIn("status", ["Pending", "Playing"])
        ->exists();

        if ($activeGame) {
            return response()->json(["message" => "You already have an active game."], 400);
        }

        $game = Game::create([
            "type" => $validated["type"],
            "status" => "Pending",
            "player1_user_id" => $user->id,
            "player2_user_id" => self::GHOST_ID, 
            "winner_user_id" => self::GHOST_ID,
            "loser_user_id" => self::GHOST_ID,
            "began_at" => now(),
            "player1_points" => 0,
            "player2_points" => 0,
            "custom" => null,
        ]);

        return response()->json([
            "message" => "Multiplayer game room created",
            "game" => $game,
        ], 201);
    }

    public function join(Game $game)
    {
        $this->authorize('join', $game);
        
        $user = Auth::user();

        if ($game->player1_user_id == $user->id) {
            return response()->json([
                "message" => "You are the host. Waiting for opponent...",
                "game" => $game
            ], 200);
        }

        if ($game->player2_user_id !== self::GHOST_ID) {
            return response()->json(["message" => "Game is full"], 400);
        }

        $game->update([
            "status" => "Playing",
            "player2_user_id" => $user->id,
        ]);

        return response()->json([
            "message" => "Joined successfully!",
            "game" => $game,
        ], 200);
    }

    public function show(Game $game)
    {
        $this->authorize('view', $game);
        
        $game->load(["player1", "player2", "winner"]);
        return response()->json($game);
    }

    public function update(Request $request, Game $game)
    {
        $this->authorize('update', $game);
        
        if ($game->status == "Ended") {
            return response()->json(["message" => "Game already ended"], 400);
        }

        $data = $request->validate([
            "status" => "in:Playing,Ended,Interrupted",
            "winner_user_id" => "exists:users,id",
            "loser_user_id" => "exists:users,id",
            "player1_points" => "integer",
            "player2_points" => "integer",
            "is_draw" => "boolean",
            "total_time" => "numeric",
        ]);

        if (isset($data["status"]) && $data["status"] === "Ended") {
            $data["ended_at"] = now();
        }

        $game->update($data);

        return response()->json($game);
    }

    public function resign(Game $game)
    {
        $this->authorize('resign', $game);
        
        $user = Auth::user();
        
        $game->update([
            'status' => 'Ended',
            'winner_user_id' => $game->player1_user_id === $user->id 
                ? $game->player2_user_id 
                : $game->player1_user_id,
            'loser_user_id' => $user->id,
            'ended_at' => now(),
        ]);

        return response()->json([
            'message' => 'You have resigned from the game',
            'game' => $game->fresh(),
        ]);
    }
}
