<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\Password;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'confirmed', Password::defaults()],
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 422);
        }

        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        $token = $user->createToken('auth_token')->plainTextToken;

        return response()->json([
            'message' => __('auth.registered'),
            'user' => $user,
            'token' => $token,
        ], 201);
    }

    public function login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => ['required', 'string', 'email'],
            'password' => ['required', 'string'],
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 422);
        }

        $user = User::where('email', $request->email)->first();

        if (!$user || !Hash::check($request->password, $user->password)) {
            return response()->json([
                'message' => __('auth.failed'),
            ], 401);
        }

        // Check if 2FA is enabled
        if ($user->isTwoFactorEnabled()) {
            return response()->json([
                'requires_2fa' => true,
                'user_id' => $user->id,
                'message' => __('auth.2fa_required'),
            ]);
        }

        $token = $user->createToken('auth_token')->plainTextToken;

        return response()->json([
            'message' => __('auth.logged_in'),
            'user' => $user,
            'token' => $token,
        ]);
    }

    public function verify2FA(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'user_id' => ['required', 'integer', 'exists:users,id'],
            'code' => ['required', 'string', 'size:6'],
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 422);
        }

        $user = User::find($request->user_id);

        if (!$user || !$user->isTwoFactorEnabled()) {
            return response()->json(['message' => __('auth.2fa_not_enabled')], 400);
        }

        $google2fa = app('pragmarx.google2fa');
        $secret = $user->getTwoFactorSecret();

        $valid = $google2fa->verifyKey($secret, $request->code);

        if (!$valid) {
            // Check recovery codes
            $recoveryCodes = $user->two_factor_recovery_codes ?? [];
            if (in_array($request->code, $recoveryCodes)) {
                // Remove used recovery code
                $user->two_factor_recovery_codes = array_diff($recoveryCodes, [$request->code]);
                $user->save();
                $valid = true;
            }
        }

        if (!$valid) {
            return response()->json(['message' => __('auth.2fa_invalid')], 401);
        }

        $token = $user->createToken('auth_token')->plainTextToken;

        return response()->json([
            'message' => __('auth.logged_in'),
            'user' => $user,
            'token' => $token,
        ]);
    }

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

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

    public function user(Request $request)
    {
        return response()->json([
            'user' => $request->user(),
        ]);
    }
}
