<?php

namespace App\Http\Controllers;

use App\Http\Requests\Auth\LoginRequest;
use App\Http\Requests\Auth\RegisterRequest;
use App\Models\User;
use Hash;
use Illuminate\Auth\Events\Verified;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\Response;

class AuthController extends Controller
{
    public function register(RegisterRequest $request): JsonResponse
    {
        $data = $request->validated();

        $avatar_uri = null;

        if ($request->hasFile('avatar')) {
            $filename = \Illuminate\Support\Str::uuid().'.jpg';
            $path = $request->file('avatar')->storeAs('avatars', $filename, 'public');
            $avatar_uri = $path;
        }

        $user = User::create([
            'username' => $data['username'],
            'email' => $data['email'],
            'password' => $data['password'],
            'avatar_uri' => $avatar_uri,
        ]);

        $token = $user->createToken(
            $this->resolveDeviceName($data)
        )->plainTextToken;

        $user->sendEmailVerificationNotification();

        return response()->json([
            'token' => $token,
            'token_type' => 'Bearer',

        ], Response::HTTP_CREATED);
    }

    public function login(LoginRequest $request): JsonResponse
    {
        $data = $request->validated();

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

        if (! $user || ! Hash::check($data['password'], $user->password)) {
            throw ValidationException::withMessages([
                'email' => [__('auth.failed')],
            ]);
        }

        if (! $user->hasVerifiedEmail()) {
            throw ValidationException::withMessages([
                'email' => [__('auth.email_not_verified')],
            ]);
        }

        $token = $user->createToken(
            $this->resolveDeviceName($data)
        )->plainTextToken;

        $user->updateLevel();
        $user->load('currentLevel');

        return response()->json([
            'token' => $token,
            'token_type' => 'Bearer',
            'user' => $user,
        ]);
    }

    public function me(Request $request): JsonResponse
    {
        /** @var \App\Models\User $user */
        $user = $request->user();
        $user->updateLevel();
        $user->load('currentLevel');

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

    public function verifyEmail(Request $request, string $id, string $hash): JsonResponse|View
    {
        $user = User::findOrFail($id);

        if (! hash_equals($hash, sha1($user->getEmailForVerification()))) {
            abort(Response::HTTP_FORBIDDEN);
        }

        if (! $user->hasVerifiedEmail()) {
            $user->markEmailAsVerified();

            event(new Verified($user));
        }

        if ($request->expectsJson()) {
            return response()->json([
                'message' => __('auth.email_verified'),
            ]);
        }

        return view('auth.email-verified');
    }

    public function resendEmailVerificationNotification(Request $request): JsonResponse
    {
        /** @var \App\Models\User $user */
        $user = $request->user();

        if ($user->hasVerifiedEmail()) {
            return response()->json([
                'message' => __('auth.email_already_verified'),
            ]);
        }

        $user->sendEmailVerificationNotification();

        return response()->json([
            'message' => __('auth.email_verification_sent'),
        ]);
    }

    public function logout(Request $request): JsonResponse
    {
        $request->user()?->currentAccessToken()?->delete();

        return response()->json([
            'message' => __('auth.logout_success'),
        ]);
    }

    /**
     * Determine the token name to use for the access token.
     *
     * @param  array<string, mixed>  $data
     */
    private function resolveDeviceName(array $data): string
    {
        $deviceName = trim((string) ($data['device_name'] ?? ''));

        return $deviceName !== '' ? $deviceName : 'api-token';
    }

    public function softDelete(Request $request): JsonResponse
    {
        $user = $request->user(); // ou $request->user('sanctum')

        if (! $user) {
            return response()->json(['message' => 'Unauthenticated.'], 401);
        }

        $user->delete(); // <= Soft delete si SoftDeletes est activé

        return response()->json([
            'message' => __('auth.soft_delete_success'),
        ]);
    }
}
