<?php

namespace PloverCRM\Modules\Automations\Services;

use PloverCRM\Core\Container;

/**
 * Listens to CRM lifecycle events and dispatches automations.
 */
class AutomationEventManager
{
    private Container $container;

    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    public function init(): void
    {
        add_action('plover_crm_after_contact_created_actions', [$this, 'handleContactCreatedAfterEnrichment'], 50, 6);
        add_action('plover_crm/contact_updated', [$this, 'handleContactUpdated'], 50, 4);
    }

    public function handleContactCreatedAfterEnrichment($contactId, $userIp, $userAgent, $currentUrl, $trackingContext, $providerId = ''): void
    {
        $payload = AutomationPayloadBuilder::buildContactCreatedAfterEnrichment(
            $this->container,
            (int) $contactId,
            $userIp,
            $userAgent,
            $currentUrl,
            $trackingContext,
            (string) $providerId
        );

        if (!$payload) {
            return;
        }

        $this->dispatchEvent('contact_created_after_enrichment', $payload);
    }

    public function handleContactUpdated($contactId, $contact, $newValues, $updateValues): void
    {
        $stageTo = isset($updateValues['stage-plover-crm']) ? (string) $updateValues['stage-plover-crm'] : '';
        if ($stageTo === '') {
            return;
        }

        $stageFrom = isset($newValues['stage-plover-crm']) ? (string) $newValues['stage-plover-crm'] : '';
        $payload = AutomationPayloadBuilder::buildContactStageChanged(
            $this->container,
            (int) $contactId,
            is_array($contact) ? $contact : [],
            $stageFrom !== '' ? $stageFrom : null,
            $stageTo,
            [
                'source' => 'contact_updated',
            ]
        );

        if (!$payload) {
            return;
        }

        $this->dispatchEvent('contact_stage_changed', $payload);
    }

    private function dispatchEvent(string $eventName, array $payload): void
    {
        $automations = AutomationRepository::getActiveByEvent($eventName);
        if (empty($automations)) {
            return;
        }

        $runner = new AutomationRunner($this->container);

        foreach ($automations as $automation) {
            $runner->run($automation, $payload);
        }
    }
}
