<?php

namespace App\Http\Controllers;

use App\Models\Game;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rule;

class UserController extends Controller
{
    /**
     * GET /api/users
     * Lista todos os utilizadores (Apenas para Admins)
     */
    public function index(Request $request)
    {
        $this->authorize('viewAny', User::class);

        $query = User::query();

        // Filtros úteis para o Backoffice
        if ($request->has('type')) {
            $query->where('type', $request->type);
        }

        if ($request->has('search')) {
            $query->where(function ($q) use ($request) {
                $q->where('name', 'like', '%'.$request->search.'%')
                    ->orWhere('email', 'like', '%'.$request->search.'%')
                    ->orWhere('nickname', 'like', '%'.$request->search.'%');
            });
        }

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

    /**
     * POST /api/users
     * Registar um novo utilizador (Admin only)
     */
    public function store(Request $request)
    {
        $this->authorize('create', User::class);

        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'nickname' => 'required|string|max:20|unique:users,nickname',
            'email' => 'required|email|unique:users,email',
            'password' => 'required|string|min:3',
            'type' => 'required|in:A,U',
        ]);

        $validated['password'] = Hash::make($validated['password']);

        $user = User::create($validated);

        return response()->json($user, 201);
    }

    /**
     * GET /api/users/me
     * Retorna o perfil do utilizador autenticado atual.
     * Usado pelo VueJS para saber quem está logado.
     */
    public function me(Request $request)
    {
        return response()->json($request->user());
    }

    /**
     * GET /api/users/{user}
     * Mostra um perfil específico.
     */
    public function show(User $user)
    {
        $currentUser = Auth::user();

        // Admins and owners get full profile, others get limited view
        if ($currentUser->type === 'A' || $currentUser->id === $user->id) {
            return response()->json($user);
        } else {
            return response()->json([
                'id' => $user->id,
                'name' => $user->name,
                'nickname' => $user->nickname,
                'photo_avatar_filename' => $user->photo_avatar_filename,
                'type' => $user->type,
            ]);
        }
    }

    /**
     * PUT/PATCH /api/users/{user}
     * Atualizar perfil (Nome, Nickname, Password, Foto)
     */
    public function update(Request $request, User $user)
    {
        $this->authorize('update', $user);
        
        $validated = $request->validate([
            'name' => 'sometimes|string|max:255',
            'nickname' => [
                'sometimes',
                'string',
                'max:20',
                Rule::unique('users')->ignore($user->id),
            ],
            'email' => [
                'sometimes',
                'email',
                Rule::unique('users')->ignore($user->id),
            ],
            'password' => 'sometimes|string|min:3',
        ]);

        // Lógica de Upload de Foto (Exemplo Básico)
        // if ($request->hasFile('photo_avatar')) {
        //     $path = $request->file('photo_avatar')->store('avatars', 'public');
        //     $validated['photo_avatar_filename'] = basename($path);
        // }

        $user->update($validated);

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


    public function updatePassword(Request $request, User $user)
    {
        $this->authorize('update', $user);

        $validated = $request->validate([
            'current_password' => 'required|string',
            'new_password' => 'required|string|min:3|confirmed',
        ]);

        // Verificar se a password atual está correta
        if (!Hash::check($validated['current_password'], $user->password)) {
            return response()->json(['message' => 'Current password is incorrect'], 403);
        }

        // Atualizar para a nova password
        $user->password = Hash::make($validated['new_password']);
        $user->save();

        return response()->json(['message' => 'Password updated successfully']);
    }

    /**
     * DELETE /api/users/{user}
     * Apagar conta (Soft Delete)
     */
    public function destroy(User $user)
    {
        $this->authorize('delete', $user);

        // Check if user has transactions or games - if so, soft delete
        $hasTransactions = $user->transactions()->exists();
        $hasGames = Game::where(function ($q) use ($user) {
            $q->where('player1_user_id', $user->id)
                ->orWhere('player2_user_id', $user->id);
        })->exists();

        if ($hasTransactions || $hasGames) {
            $user->delete(); // Soft delete
            $message = 'User account deactivated (soft-deleted due to transaction/game history)';
        } else {
            $user->forceDelete(); // Hard delete
            $message = 'User permanently deleted';
        }

        return response()->json(['message' => $message]);
    }

    /**
     * GET /api/users/{user}/matches
     * Histórico de Jogos Multiplayer do Utilizador
     */
    public function getMatches(Request $request, User $user)
    {
        $this->authorize('view', $user);

        $outcomeSql = "CASE 
            WHEN is_draw = 1 THEN 'DRAW'
            WHEN winner_user_id = {$user->id} THEN 'WIN'
            ELSE 'LOSS'
        END";

        $query = Game::query()
        ->select('*')
        ->selectRaw("($outcomeSql) as outcome_text")
        ->where(function ($q) use ($user) {
            $q->where('player1_user_id', $user->id)
              ->orWhere('player2_user_id', $user->id);
        })
        ->with(['winner', 'player1', 'player2']);

        if ($request->has('type')) {
            $query->where('type', $request->type); 
        }

        if ($request->has('status')) {
            $query->where('status', $request->status);
        }

        if ($request->filled('outcome')) {
        switch ($request->outcome) {
            case 'win':
                $query->where('winner_user_id', $user->id)
                      ->where('is_draw', 0);
                break;
            case 'loss':
            case 'forfeit': // Forfeit treated as loss for now
                $query->where('loser_user_id', $user->id)
                      ->where('is_draw', 0);
                break;
            case 'draw':
                $query->where('is_draw', 1);
                break;
        }
    }

        if ($request->has('date_from')) {
            $query->whereDate('began_at', '>=', $request->date_from);
        }

        if ($request->has('date_to')) {
            $query->whereDate('ended_at', '<=', $request->date_to);
        }

        $order = $request->get('sort_by', 'began_at');
        $direction = $request->get('sort_direction', 'desc');

        if ($order === 'outcome') {
            $query->orderBy('outcome_text', $direction);
        } else {
            $query->orderBy($order, $direction);
        }

        $matches = $query->orderBy($order, $direction)
                              ->paginate(10);

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

    public function block(User $user)
    {
        $this->authorize('block', $user);

        $user->blocked = true;
        $user->save();

        // Revoke all active tokens for immediate effect
        $user->tokens()->delete();

        return response()->json(['message' => 'User blocked successfully']);
    }

    public function unblock(User $user)
    {
        $this->authorize('unblock', $user);

        $user->blocked = false;
        $user->save();

        return response()->json(['message' => 'User unblocked successfully']);
    }

    public function getTransactions(Request $request, User $user)
    {
        if ($request->user()->id !== $user->id && $request->user()->type !== 'A') {
            return response()->json(['message' => 'Forbidden'], 403);
        }

        $query = $user->transactions()->with('type');

        if ($request->has('type')) {
            $query->whereHas('type', function ($q) use ($request) {
                $q->where('type', $request->type);
            });
        }

        if ($request->has('date_from')) {
            $query->whereDate('transaction_datetime', '>=', $request->date_from);
        }

        if ($request->has('date_to')) {
            $query->whereDate('transaction_datetime', '<=', $request->date_to);
        }

        $transactions = $query->orderBy('transaction_datetime', 'desc')
                              ->paginate(10);

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

    public function getMyTransactions(Request $request)
    {
        return $this->getTransactions($request, $request->user());
    }
}
