<?php

namespace App\Services\Auth;

use App\Enums\PlatformEnum;
use App\Exceptions\PlatformAuthException;
use App\Models\PlatformAccount;
use App\Modules\Lemmy\Services\LemmyApiService;
use Exception;

class LemmyAuthService
{
    /**
     * @throws PlatformAuthException
     */
    public function getToken(PlatformAccount $account): string
    {
        // Use cached token if available
        $cachedToken = $account->settings['api_token'] ?? null;
        if ($cachedToken) {
            return $cachedToken;
        }

        return $this->refreshToken($account);
    }

    /**
     * Clear cached token and re-authenticate.
     *
     * @throws PlatformAuthException
     */
    public function refreshToken(PlatformAccount $account): string
    {
        if (! $account->username || ! $account->password || ! $account->instance_url) {
            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Missing credentials for account: '.$account->username);
        }

        $api = new LemmyApiService($account->instance_url);
        $token = $api->login($account->username, $account->password);

        if (! $token) {
            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Login failed for account: '.$account->username);
        }

        // Cache the token for future use
        $settings = $account->settings ?? [];
        $settings['api_token'] = $token;
        $account->update(['settings' => $settings]);

        return $token;
    }

    /**
     * Authenticate with Lemmy API and return user data with JWT
     *
     * @throws PlatformAuthException
     */
    /**
     * @return array<string, mixed>
     */
    public function authenticate(string $instanceUrl, string $username, string $password): array
    {
        try {
            $api = new LemmyApiService($instanceUrl);
            $token = $api->login($username, $password);

            if (! $token) {
                // Throw a clean exception that will be caught and handled by the controller
                throw new PlatformAuthException(PlatformEnum::LEMMY, 'Invalid credentials');
            }

            // Get user info with the token
            // For now, we'll return a basic response structure
            // In a real implementation, you might want to fetch user details
            return [
                'jwt' => $token,
                'person_view' => [
                    'person' => [
                        'id' => 0, // Would need API call to get actual user info
                        'display_name' => null,
                        'bio' => null,
                    ],
                ],
            ];
        } catch (PlatformAuthException $e) {
            // Re-throw PlatformAuthExceptions as-is to avoid nesting
            throw $e;
        } catch (Exception $e) {
            // Check if it's a rate limit error
            if (str_contains($e->getMessage(), 'Rate limited by')) {
                throw new PlatformAuthException(PlatformEnum::LEMMY, $e->getMessage());
            }
            // Check if it's a connection failure
            if (str_contains($e->getMessage(), 'Connection failed')) {
                throw new PlatformAuthException(PlatformEnum::LEMMY, 'Connection failed');
            }
            // For other exceptions, throw a clean PlatformAuthException
            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Connection failed');
        }
    }
}
