<?php

namespace App\Services\Platforms\Auth;

use App\Contracts\PlatformTokenRefresher;
use App\Models\PlatformConnection;
use Illuminate\Support\Facades\Http;
use RuntimeException;

class LinkedInTokenRefresher implements PlatformTokenRefresher
{
    public function refresh(PlatformConnection $connection): PlatformConnection
    {
        $refreshToken = (string) $connection->refresh_token;

        if (blank($refreshToken)) {
            $error = 'LinkedIn connection cannot be refreshed: refresh_token is missing.';
            $connection->update(['last_error' => $error]);

            throw new RuntimeException($error);
        }

        $clientId = (string) ($connection->platform_data['client_id'] ?? config('platforms.linkedin.client_id'));
        $clientSecret = (string) ($connection->platform_data['client_secret'] ?? config('platforms.linkedin.client_secret'));

        $response = Http::asForm()
            ->connectTimeout(5)
            ->timeout(10)
            ->post('https://www.linkedin.com/oauth/v2/accessToken', [
                'grant_type' => 'refresh_token',
                'refresh_token' => $refreshToken,
                'client_id' => $clientId,
                'client_secret' => $clientSecret,
            ]);

        if ($response->failed() || ! is_string($response->json('access_token'))) {
            $error = sprintf('LinkedIn OAuth token refresh failed: %s', $response->body());
            $connection->update(['last_error' => $error]);

            throw new RuntimeException($error);
        }

        $expiresIn = (int) $response->json('expires_in', 5184000); // 60 days standard
        $updates = [
            'access_token' => (string) $response->json('access_token'),
            'expires_at' => now()->addSeconds($expiresIn),
            'last_refreshed_at' => now(),
            'last_error' => null,
        ];

        // If LinkedIn rotates the refresh token
        if ($newRefresh = $response->json('refresh_token')) {
            $updates['refresh_token'] = (string) $newRefresh;
        }

        if ($refreshExpiresIn = $response->json('refresh_token_expires_in')) {
            $updates['refresh_expires_at'] = now()->addSeconds((int) $refreshExpiresIn);
        }

        $connection->update($updates);

        return $connection->fresh();
    }
}
