<?php

namespace App\Http\Controllers\Api\Auth;

use App\Http\Controllers\Api\BaseApiController;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use PHPOpenSourceSaver\JWTAuth\Facades\JWTAuth;

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

        if ($validator->fails()) {
            return $this->respondValidationError($validator->errors()->toArray());
        }

        $email = (string) $request->input('email');
        $password = (string) $request->input('password');

        $user = User::query()->where('email', $email)->first();
        if (!$user || !ci_password_verify($password, (string) $user->password)) {
            return $this->respondError('Invalid credentials.', 401);
        }

        if ((int) ($user->is_verified ?? 0) !== 1) {
            return $this->respondError('Account not verified.', 403);
        }

        if (strcasecmp((string) ($user->status ?? ''), 'Active') !== 0) {
            return $this->respondError('Account is inactive.', 403);
        }

        $jwtToken = JWTAuth::fromUser($user);
        $sanctumToken = $user->createToken('api')->plainTextToken;
        $roles = $user->roles()
            ->where('roles.is_active', 1)
            ->pluck('roles.name')
            ->values()
            ->all();

        return $this->respondSuccess([
            'user' => [
                'id' => (int) $user->id,
                'firstname' => $user->firstname,
                'lastname' => $user->lastname,
                'email' => $user->email,
                'roles' => $roles,
            ],
            'jwt' => [
                'access_token' => $jwtToken,
                'token_type' => 'bearer',
                'expires_in' => (int) config('jwt.ttl') * 60,
            ],
            'sanctum' => [
                'access_token' => $sanctumToken,
                'token_type' => 'bearer',
            ],
        ], 'Authenticated.');
    }

    public function refresh(Request $request): JsonResponse
    {
        try {
            $newToken = JWTAuth::parseToken()->refresh();
        } catch (\Throwable $e) {
            return $this->respondError('Token refresh failed.', 401);
        }

        return $this->respondSuccess([
            'access_token' => $newToken,
            'token_type' => 'bearer',
            'expires_in' => (int) config('jwt.ttl') * 60,
        ], 'Token refreshed.');
    }

    public function me(): JsonResponse
    {
        $user = Auth::user();
        if (!$user) {
            return $this->respondError('Unauthorized.', 401);
        }

        return $this->respondSuccess([
            'id' => (int) $user->id,
            'firstname' => $user->firstname,
            'lastname' => $user->lastname,
            'email' => $user->email,
        ], 'OK');
    }

    public function logout(Request $request): JsonResponse
    {
        $token = $request->bearerToken();
        if ($token && substr_count($token, '.') === 2) {
            try {
                JWTAuth::setToken($token)->invalidate();
            } catch (\Throwable $e) {
                // ignore invalidation errors
            }
        }

        $user = $request->user();
        if ($user && method_exists($user, 'currentAccessToken')) {
            $current = $user->currentAccessToken();
            if ($current) {
                $current->delete();
            }
        }

        return $this->respondSuccess(null, 'Logged out.');
    }
}
