<?php

namespace App\Services\LinkedIn;

use App\Models\Campaign;
use App\Services\Platforms\Support\CallLogger;
use Illuminate\Support\Facades\Log;

/**
 * Unified facade for LinkedIn Ads.
 *
 * Coordinates LinkedIn operations through guardrails and audit logging.
 */
class LinkedIn
{
    public function __construct(
        private readonly LinkedInRestApi $api,
        private readonly CallLogger $log,
    ) {}

    /**
     * Attribute subsequent calls to a campaign draft in the audit trail.
     */
    public function on(?int $campaignId, ?string $actor): static
    {
        $this->log->attributeTo($campaignId, $actor);

        return $this;
    }

    /**
     * @return list<array<string,mixed>>
     */
    public function adAccounts(): array
    {
        return $this->api->adAccounts();
    }

    public function createCampaignGroup(string $adAccountId, string $name, string $status = 'PAUSED'): string
    {
        $response = $this->api->createCampaignGroup($adAccountId, [
            'name' => $name,
            'status' => $status,
        ]);

        return (string) ($response['id'] ?? '');
    }

    public function createCampaign(string $adAccountId, array $payload): string
    {
        $response = $this->api->createCampaign($adAccountId, $payload);

        return (string) ($response['id'] ?? '');
    }

    public function createCreative(string $adAccountId, array $payload): string
    {
        $response = $this->api->createCreative($adAccountId, $payload);

        return (string) ($response['id'] ?? '');
    }

    public function createPost(array $payload, ?string $adAccountId = null): string
    {
        $response = $this->api->createPost($payload, $adAccountId);

        return (string) ($response['id'] ?? '');
    }

    public function uploadImage(string $adAccountId, string $filePath, ?string $name = null, ?string $ownerUrn = null): string
    {
        return $this->api->uploadImage($adAccountId, $filePath, $name, $ownerUrn);
    }

    public function publish(string $adAccountId, string $campaignId): void
    {
        if (! config('platforms.linkedin.publish_enabled', false)) {
            Log::info("LinkedIn live publishing is disabled (LINKEDIN_PUBLISH_ENABLED=false). Campaign {$campaignId} will remain PAUSED.");

            return;
        }

        $this->api->updateEntity($adAccountId, 'campaign', $campaignId, [
            'status' => 'ACTIVE',
        ]);
    }

    public function pause(string $adAccountId, string $campaignId): void
    {
        $this->api->updateEntity($adAccountId, 'campaign', $campaignId, [
            'status' => 'PAUSED',
        ]);
    }

    /**
     * Change fields on a live campaign.
     *
     * publish() and pause() already went through updateEntity to set one field,
     * so the route existed and only the status ever used it. Named here rather
     * than left to callers reaching past this wrapper into the REST client,
     * which is what the wrapper is for: on() carries the campaign and actor
     * that make the call auditable.
     *
     * @param  array<string, mixed>  $fields
     */
    public function updateCampaign(string $adAccountId, string $campaignId, array $fields): void
    {
        $this->api->updateEntity($adAccountId, 'campaign', $campaignId, $fields);
    }

    public function delete(string $adAccountId, string $entityType, string $entityId): bool
    {
        return $this->api->delete($adAccountId, $entityType, $entityId);
    }
}
