<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class AuthController extends Controller
{
    private const MAX_TOKENS = 5;

    public function login(Request $request): JsonResponse
    {
        $credentials = $request->validate([
            'email' => ['required', 'email'],
            'password' => ['required', 'string'],
        ]);

        $user = User::where('email', $credentials['email'])->first();

        if (! $user || ! Hash::check($credentials['password'], $user->password)) {
            return response()->json(['message' => 'Invalid email or password.'], 401);
        }

        $token = Str::random(60);
        $hash  = hash('sha256', $token);

        DB::transaction(function () use ($user, $hash) {
            // Evict oldest tokens if at the limit
            $existing = DB::table('user_tokens')
                ->where('user_id', $user->id)
                ->orderBy('created_at')
                ->pluck('id');

            if ($existing->count() >= self::MAX_TOKENS) {
                DB::table('user_tokens')
                    ->whereIn('id', $existing->take($existing->count() - self::MAX_TOKENS + 1))
                    ->delete();
            }

            DB::table('user_tokens')->insert([
                'user_id'    => $user->id,
                'token_hash' => $hash,
                'created_at' => now(),
            ]);
        });

        return response()->json([
            'user'  => $user->only(['id', 'name', 'email']),
            'token' => $token,
        ]);
    }

    public function me(Request $request): JsonResponse
    {
        $user = $this->userFromToken($request);
        if (! $user) {
            return response()->json(['message' => 'Unauthenticated.'], 401);
        }
        return response()->json(['user' => $user->only(['id', 'name', 'email'])]);
    }

    public function logout(Request $request): JsonResponse
    {
        $token = $request->bearerToken();
        if ($token) {
            DB::table('user_tokens')
                ->where('token_hash', hash('sha256', $token))
                ->delete();
        }
        return response()->json(['message' => 'Logged out.']);
    }

    private function userFromToken(Request $request): ?User
    {
        $token = $request->bearerToken();
        if (! $token) return null;

        $row = DB::table('user_tokens')
            ->where('token_hash', hash('sha256', $token))
            ->first();

        return $row ? User::find($row->user_id) : null;
    }
}
