<?php

declare(strict_types=1);

namespace MauticPlugin\DealFlowBundle\EventSubscriber;

use Mautic\WebhookBundle\Event\WebhookBuilderEvent;
use Mautic\WebhookBundle\Model\WebhookModel;
use Mautic\WebhookBundle\WebhookEvents;
use MauticPlugin\DealFlowBundle\DealFlowEvents;
use MauticPlugin\DealFlowBundle\Event\DealEvent;
use MauticPlugin\DealFlowBundle\Service\DealContextBuilder;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

final class WebhookSubscriber implements EventSubscriberInterface
{
    public function __construct(
        private readonly WebhookModel $webhookModel,
        private readonly DealContextBuilder $contextBuilder,
    ) {
    }

    public static function getSubscribedEvents(): array
    {
        return [
            WebhookEvents::WEBHOOK_ON_BUILD => 'onWebhookBuild',
            DealFlowEvents::DEAL_CREATED => 'onDealEvent',
            DealFlowEvents::DEAL_UPDATED => 'onDealEvent',
            DealFlowEvents::DEAL_STAGE_CHANGED => 'onDealEvent',
            DealFlowEvents::DEAL_CLOSED_WON => 'onDealEvent',
            DealFlowEvents::DEAL_CLOSED_LOST => 'onDealEvent',
            DealFlowEvents::DEAL_CONTACT_ATTACHED => 'onDealEvent',
            DealFlowEvents::DEAL_COMPANY_CHANGED => 'onDealEvent',
            DealFlowEvents::DEAL_OWNER_ASSIGNED => 'onDealEvent',
            DealFlowEvents::DEAL_OWNER_REASSIGNED => 'onDealEvent',
            DealFlowEvents::DEAL_NOTE_ADDED => 'onDealEvent',
            DealFlowEvents::DEAL_TASK_ADDED => 'onDealEvent',
            DealFlowEvents::DEAL_TASK_COMPLETED => 'onDealEvent',
            DealFlowEvents::DEAL_TASK_UPDATED => 'onDealEvent',
            DealFlowEvents::DEAL_TASK_DELETED => 'onDealEvent',
            DealFlowEvents::DEAL_CONTACT_DETACHED => 'onDealEvent',
            DealFlowEvents::DEAL_FIELD_UPDATED => 'onDealEvent',
            DealFlowEvents::DEAL_ATTACHMENT_ADDED => 'onDealEvent',
            DealFlowEvents::DEAL_ATTACHMENT_DELETED => 'onDealEvent',
        ];
    }

    public function onWebhookBuild(WebhookBuilderEvent $event): void
    {
        $events = [
            DealFlowEvents::DEAL_CREATED => ['label' => 'mautic.dealflow.webhook.event.deal.created', 'description' => 'mautic.dealflow.webhook.event.deal.created_desc'],
            DealFlowEvents::DEAL_UPDATED => ['label' => 'mautic.dealflow.webhook.event.deal.updated', 'description' => 'mautic.dealflow.webhook.event.deal.updated_desc'],
            DealFlowEvents::DEAL_STAGE_CHANGED => ['label' => 'mautic.dealflow.webhook.event.deal.stage_changed', 'description' => 'mautic.dealflow.webhook.event.deal.stage_changed_desc'],
            DealFlowEvents::DEAL_CLOSED_WON => ['label' => 'mautic.dealflow.webhook.event.deal.closed_won', 'description' => 'mautic.dealflow.webhook.event.deal.closed_won_desc'],
            DealFlowEvents::DEAL_CLOSED_LOST => ['label' => 'mautic.dealflow.webhook.event.deal.closed_lost', 'description' => 'mautic.dealflow.webhook.event.deal.closed_lost_desc'],
            DealFlowEvents::DEAL_NOTE_ADDED => ['label' => 'mautic.dealflow.webhook.event.deal.note_added', 'description' => 'mautic.dealflow.webhook.event.deal.note_added_desc'],
            DealFlowEvents::DEAL_TASK_ADDED => ['label' => 'mautic.dealflow.webhook.event.deal.task_added', 'description' => 'mautic.dealflow.webhook.event.deal.task_added_desc'],
            DealFlowEvents::DEAL_TASK_COMPLETED => ['label' => 'mautic.dealflow.webhook.event.deal.task_completed', 'description' => 'mautic.dealflow.webhook.event.deal.task_completed_desc'],
            DealFlowEvents::DEAL_TASK_UPDATED => ['label' => 'mautic.dealflow.webhook.event.deal.task_updated', 'description' => 'mautic.dealflow.webhook.event.deal.task_updated_desc'],
            DealFlowEvents::DEAL_TASK_DELETED => ['label' => 'mautic.dealflow.webhook.event.deal.task_deleted', 'description' => 'mautic.dealflow.webhook.event.deal.task_deleted_desc'],
            DealFlowEvents::DEAL_CONTACT_DETACHED => ['label' => 'mautic.dealflow.webhook.event.deal.contact_detached', 'description' => 'mautic.dealflow.webhook.event.deal.contact_detached_desc'],
            DealFlowEvents::DEAL_FIELD_UPDATED => ['label' => 'mautic.dealflow.webhook.event.deal.field_updated', 'description' => 'mautic.dealflow.webhook.event.deal.field_updated_desc'],
            DealFlowEvents::DEAL_ATTACHMENT_ADDED => ['label' => 'mautic.dealflow.webhook.event.deal.attachment_added', 'description' => 'mautic.dealflow.webhook.event.deal.attachment_added_desc'],
            DealFlowEvents::DEAL_ATTACHMENT_DELETED => ['label' => 'mautic.dealflow.webhook.event.deal.attachment_deleted', 'description' => 'mautic.dealflow.webhook.event.deal.attachment_deleted_desc'],
        ];

        foreach ($events as $key => $definition) {
            $event->addEvent($key, $definition);
        }
    }

    public function onDealEvent(DealEvent $event, string $eventName): void
    {
        $payload = $this->contextBuilder->buildWebhookPayload(
            $event->getDeal(),
            $eventName,
            $event->getOrigin(),
            $event->getActorType(),
            $event->getActorId(),
            $event->getPayload()
        );

        $this->webhookModel->queueWebhooksByType($eventName, $payload);
    }
}
