<?php

namespace App\Http\Controllers;

use App\Mail\AvisoCambioPw;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Laravel\Sanctum\PersonalAccessToken;
use Illuminate\Validation\Rules;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Hash;

class TokenController extends Controller
{
    /**
     * Cierra sesión API: revoca el token Bearer actual (Sanctum).
     */
    public function logout(Request $request): JsonResponse
    {
        $user = $request->user();
        if ($user === null) {
            return response()->json(['message' => 'No autenticado.'], JsonResponse::HTTP_UNAUTHORIZED);
        }

        $bearer = $request->bearerToken();
        if ($bearer !== null) {
            $accessToken = PersonalAccessToken::findToken($bearer);
            if ($accessToken !== null) {
                $accessToken->delete();
            }
        } else {
            $current = $user->currentAccessToken();
            if ($current instanceof PersonalAccessToken) {
                $current->delete();
            }
        }

        return response()->json(null, JsonResponse::HTTP_NO_CONTENT);
    }

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

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

        if ($user === null) {
            throw ValidationException::withMessages([
                'email' => ['Correo o contraseña incorrectos.'],
            ]);
        }

        if (! Hash::check($request->password, $user->password)) {
            throw ValidationException::withMessages([
                'password' => ['Correo o contraseña incorrectos.'],
            ]);
        }

        if ($user->roles()->where('guard_name', 'web')->doesntExist()) {
            return response()->json([
                'message' => 'Tu cuenta no tiene rol asignado. Contacta al administrador del rancho.',
            ], JsonResponse::HTTP_FORBIDDEN);
        }

        $tokenName = $request->input('device') === 'mobile' ? 'mobile-campo' : 'web-session';
        $token = $user->createToken($tokenName);

        return response()->json([
            'data' => $token->plainTextToken,
            'user' => [
                'id' => $user->id,
                'name' => $user->name,
                'email' => $user->email,
                'roles' => $user->getRoleNames('web')->toArray(),
            ],
        ], JsonResponse::HTTP_OK);
    }

    public function expire(PersonalAccessToken $token): JsonResponse
    {
        $token->update([
            'expires_at' => now(),
        ]);

        return response()->json(null, JsonResponse::HTTP_NO_CONTENT);
    }

    public function createResetPW(Request $request): JsonResponse
    {
        $request->validate([
            'email' => 'required|exists:users,email',
        ]);
        $user = User::where(['email' => $request->email])->first();
        if ($user) {
            $user->update([
                'uuid' => Str::uuid()->toString(),
            ]);
            Mail::to($user->email)->send(new AvisoCambioPw($user));

            return response()->json([
                'data' => true,
            ], JsonResponse::HTTP_OK);
        }

        throw ValidationException::withMessages(['email' => [trans('auth.failed')]]);
    }

    public function saveResetPW(Request $request): JsonResponse
    {
        $request->validate([
            'uuid' => 'required|exists:users,uuid',
            'password' => ['required', 'confirmed', Rules\Password::defaults()],
        ]);
        $user = User::where(['uuid' => $request->uuid])->first();
        if ($user) {
            $user->update([
                'uuid' => null,
                'password' => Hash::make($request->password),
            ]);

            return response()->json([
                'data' => true,
            ], JsonResponse::HTTP_OK);
        }

        throw ValidationException::withMessages(['email' => [trans('auth.failed')]]);
    }

    public function getUserUuid(Request $request): JsonResponse
    {
        $request->validate([
            'uuid' => 'required|exists:users,uuid',
        ]);
        $user = User::where(['uuid' => $request->uuid])->first();
        if ($user) {
            return response()->json([
                'data' => $user,
            ], JsonResponse::HTTP_OK);
        }

        throw ValidationException::withMessages(['email' => [trans('auth.failed')]]);
    }
}
