<?php

declare(strict_types=1);

namespace ImovelZapAi\Publishing\Connectors\GroupOlx\Application\Services;

use ImovelZapAi\Publishing\Connectors\GroupOlx\Application\Actions\GenerateVrsyncFeedAction;
use ImovelZapAi\Publishing\Connectors\GroupOlx\Application\Data\GroupOlxPublicFeedData;
use ImovelZapAi\Publishing\Connectors\GroupOlx\Application\Ports\GroupOlxConnectorInterface;
use ImovelZapAi\Publishing\Connectors\GroupOlx\Application\Ports\GroupOlxFeedBuilderInterface;
use ImovelZapAi\Publishing\Connectors\GroupOlx\Application\Ports\GroupOlxFeedValidatorInterface;
use ImovelZapAi\Publishing\Connectors\GroupOlx\Application\Ports\GroupOlxPublicFeedInterface;
use ImovelZapAi\Publishing\Connectors\GroupOlx\Domain\Exceptions\GroupOlxConnectorException;
use ImovelZapAi\Publishing\Connectors\GroupOlx\Domain\GroupOlxConnector as GroupOlxConnectorIdentity;
use ImovelZapAi\Publishing\Domain\Canonical\NormalizedListing;

/**
 * Orquestra o conector Grupo OLX a partir de NormalizedListing.
 */
final class GroupOlxConnector implements GroupOlxConnectorInterface
{
    public function __construct(
        private readonly GroupOlxFeedBuilderInterface $feedBuilder,
        private readonly GroupOlxFeedValidatorInterface $validator,
        private readonly GroupOlxPublicFeedInterface $publicFeed,
        private readonly GenerateVrsyncFeedAction $generateFeed,
    ) {}

    public function slug(): string
    {
        return GroupOlxConnectorIdentity::SLUG;
    }

    public function publishFeed(string $tenantId, array $listings): GroupOlxPublicFeedData
    {
        if ($listings === []) {
            throw GroupOlxConnectorException::invalidFeed('Nenhum imóvel para publicar.');
        }

        $build = $this->feedBuilder->build($listings);
        $validation = $this->validator->validateBuild($build);

        if (! $validation->isValid()) {
            throw GroupOlxConnectorException::invalidFeed($validation->firstError() ?? 'Feed inválido.');
        }

        return $this->publicFeed->publish($tenantId, $build->xml, $build->listingCount());
    }

    public function publishListing(string $tenantId, NormalizedListing $listing): GroupOlxPublicFeedData
    {
        return $this->publishFeed($tenantId, [$listing]);
    }

    public function publicFeedUrl(string $tenantId): string
    {
        return $this->publicFeed->resolveUrl($tenantId);
    }

    /**
     * Regenera o feed do tenant a partir dos imóveis publicados (uso do worker).
     */
    public function regenerateFromPublished(string $tenantId): bool
    {
        return $this->generateFeed->execute($tenantId);
    }
}
