<?php

namespace App\Providers;

use App\Models\PlatformConnection;
use App\Services\LinkedIn\LinkedIn;
use App\Services\LinkedIn\LinkedInRestApi;
use App\Services\Meta\AdsMcp;
use App\Services\Meta\GraphApi;
use App\Services\Meta\Meta;
use App\Services\Platforms\Support\CallLogger;
use Illuminate\Support\ServiceProvider;

/**
 * Wires the platform transports.
 *
 * The guardrails and the audit log live in CallLogger, which both transports go
 * through. That placement is the point: a new platform inherits the ad-account
 * allow list, the hourly call budget and the full audit trail by existing,
 * rather than by remembering to reimplement them.
 */
class PlatformServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->scoped(CallLogger::class);

        $this->app->scoped(GraphApi::class, fn ($app): GraphApi => new GraphApi(
            (string) (PlatformConnection::shared('meta')?->access_token ?: config('platforms.meta.token')),
            (string) config('platforms.meta.version'),
            $app->make(CallLogger::class),
        ));

        $this->app->scoped(Meta::class, fn ($app): Meta => new Meta(
            $app->make(GraphApi::class),
            $this->mcp($app),
            $app->make(CallLogger::class),
        ));

        $this->app->scoped(LinkedInRestApi::class, fn ($app): LinkedInRestApi => new LinkedInRestApi(
            (string) (PlatformConnection::shared('linkedin')?->access_token ?: config('platforms.linkedin.token')),
            (string) config('platforms.linkedin.version', '202401'),
            $app->make(CallLogger::class),
        ));

        $this->app->scoped(LinkedIn::class, fn ($app): LinkedIn => new LinkedIn(
            $app->make(LinkedInRestApi::class),
            $app->make(CallLogger::class),
        ));
    }

    /**
     * The MCP is optional. Without a token, or with it switched off, every
     * operation falls through to Graph rather than failing, so a missing or
     * expired MCP token degrades the product instead of breaking it.
     */
    private function mcp($app): ?AdsMcp
    {
        $shared = PlatformConnection::shared('meta');
        $token = (string) ($shared?->platform_secrets['mcp_token'] ?? config('platforms.meta.mcp.token'));

        if (! config('platforms.meta.mcp.enabled') || $token === '') {
            return null;
        }

        return new AdsMcp(
            $token,
            (string) config('platforms.meta.mcp.endpoint'),
            $app->make(CallLogger::class),
        );
    }
}
