<?php

namespace App\Services;

use App\Models\Members\User;
use Illuminate\Support\Facades\Config;

class AuthService
{
    /**
     * 액세스 토큰과 리프레시 토큰을 함께 발급합니다.
     *
     * @param  User  $user  사용자 모델
     * @return array ['access_token' => string, 'refresh_token' => string, 'expires_in' => int, 'expires_at' => string]
     */
    public static function issueTokens(User $user): array
    {
        // 다중 기기 로그인 지원: 기존 리프레시 토큰을 삭제하지 않음
        // 각 기기에서 독립적으로 토큰 유지 가능
        // (기존 단일 기기 정책 제거 - 2026-01-15)

        // 액세스 토큰 만료 시간 (분 단위, null이면 무제한)
        $accessExpiration = Config::get('sanctum.access_token_expiration');
        $accessExpiration = $accessExpiration ? (int) $accessExpiration : null;
        $accessExpiresAt = $accessExpiration ? now()->addMinutes($accessExpiration) : null;

        // 리프레시 토큰 만료 시간 (분 단위, null이면 무제한)
        $refreshExpiration = Config::get('sanctum.refresh_token_expiration');
        $refreshExpiration = $refreshExpiration ? (int) $refreshExpiration : null;
        $refreshExpiresAt = $refreshExpiration ? now()->addMinutes($refreshExpiration) : null;

        // 액세스 토큰 생성
        $accessToken = $user->createToken(
            'access-token',
            ['*'],
            $accessExpiresAt
        );

        // 리프레시 토큰 생성
        $refreshToken = $user->createToken(
            'refresh-token',
            ['refresh'],
            $refreshExpiresAt
        );

        return [
            'access_token' => $accessToken->plainTextToken,
            'refresh_token' => $refreshToken->plainTextToken,
            'token_type' => 'Bearer',
            'expires_in' => $accessExpiration ? $accessExpiration * 60 : null, // 초 단위
            'expires_at' => $accessExpiresAt ? $accessExpiresAt->toDateTimeString() : null,
        ];
    }

    /**
     * 리프레시 토큰으로 새로운 액세스 토큰을 발급합니다.
     * 리프레시 토큰도 함께 갱신됩니다.
     *
     * @param  string  $refreshToken  리프레시 토큰
     * @return array|null ['access_token' => string, 'refresh_token' => string, ...] or null if invalid
     */
    public static function refreshTokens(string $refreshToken): ?array
    {
        // 리프레시 토큰 검증
        $token = \Laravel\Sanctum\PersonalAccessToken::findToken($refreshToken);

        if (! $token) {
            return null;
        }

        // 토큰 타입 확인
        if ($token->name !== 'refresh-token') {
            return null;
        }

        // 만료 확인
        if ($token->expires_at && $token->expires_at->isPast()) {
            $token->delete();

            return null;
        }

        // 사용자 조회
        $user = $token->tokenable;

        if (! $user) {
            return null;
        }

        // 기존 리프레시 토큰 삭제 (사용 후 폐기)
        $token->delete();

        // 새로운 액세스 + 리프레시 토큰 발급
        return self::issueTokens($user);
    }

    /**
     * 사용자의 모든 토큰을 삭제합니다 (로그아웃).
     *
     * @param  User  $user  사용자 모델
     */
    public static function revokeAllTokens(User $user): void
    {
        $user->tokens()->delete();
    }

    /**
     * 특정 액세스 토큰만 삭제합니다.
     *
     * @param  User  $user  사용자 모델
     * @param  string  $tokenId  토큰 ID
     */
    public static function revokeToken(User $user, string $tokenId): void
    {
        $user->tokens()->where('id', $tokenId)->delete();
    }
}
