<?php

namespace KupShop\AutomationConfiguratorBundle\Configurator\Sales\Actions;

use KupShop\AdminBundle\Util\ActivityLog;
use KupShop\AutomationConfiguratorBundle\Configurator\Interfaces\Actions\ActionInterface;
use KupShop\AutomationConfiguratorBundle\Configurator\Interfaces\Config\ActionConfig;
use KupShop\AutomationConfiguratorBundle\Configurator\Sales\SalesContext;
use KupShop\AutomationConfiguratorBundle\Event\TriggerEvent;
use KupShop\AutomationConfiguratorBundle\Exceptions\ActionRuntimeException;
use KupShop\KupShopBundle\Util\Database\QueryHint;
use KupShop\KupShopBundle\Util\Logging\SentryLogger;
use KupShop\KupShopBundle\Util\Mail\Email;
use KupShop\SalesBundle\Email\SaleEmail;
use KupShop\SalesBundle\Util\SalesUtil;
use Symfony\Contracts\Service\Attribute\Required;

class SendSystemEmail implements ActionInterface, SalesContext
{
    public const NAME = 'send_email';

    protected ?SalesUtil $salesUtil = null;

    protected SentryLogger $sentryLogger;

    protected Email $email;

    protected static array $allowedSystemEmails = [
        Email::TYPE_SALE_CREATE,
    ];

    #[Required]
    final public function setEmailService(Email $email): void
    {
        $this->email = $email;
    }

    #[Required]
    final public function setSalesUtil(?SalesUtil $salesUtil): void
    {
        $this->salesUtil = $salesUtil;
    }

    #[Required]
    final public function setSentryLogger(SentryLogger $sentryLogger): void
    {
        $this->sentryLogger = $sentryLogger;
    }

    public function getConfig()
    {
        $emailTypes = array_filter($this->email->getDefaultTypes(), fn ($x) => in_array($x, static::$allowedSystemEmails));

        $emails = array_map(function ($type) {
            $emailService = $this->email->getServiceByType($type);

            return ['key' => (string) $type, 'title' => $emailService::getName()];
        }, $emailTypes);

        return [
            'label' => 'Odeslat systémovou zprávu',
            'fields' => [
                [
                    'name' => 'order_message_type',
                    'title' => 'Typ zprávy',
                    'type' => 'select',
                    'values' => array_values($emails),
                ],
            ],
        ];
    }

    public function getName()
    {
        return self::NAME;
    }

    public function run(ActionConfig $actionConfig, $context, TriggerEvent $triggerEvent): bool
    {
        if (!($messageType = $actionConfig->getField('order_message_type')->getValue())) {
            return false;
        }

        try {
            /** @var SaleEmail $emailService */
            $emailService = $this->email->getServiceByType($messageType);
        } catch (\Exception $e) {
            throw new ActionRuntimeException("Pro prodejku č. {$context['s_code']} nebyla odeslána systémová zpráva.", ['type' => $messageType, 'error' => $e->getMessage()]);
        }

        $sale = QueryHint::withRouteToMaster(fn () => $this->salesUtil->getSale($context['id']));

        if (!$sale) {
            addActivityLog(ActivityLog::SEVERITY_ERROR,
                ActivityLog::TYPE_COMMUNICATION,
                "Pro prodejku č. {$context['s_code']} nebyla odeslána systémová zpráva.",
                ['type' => $messageType]);

            return false;
        }

        $emailService->setSale($sale);

        $message = $emailService->getEmail();
        $message['to'] = $sale->getUser()?->email;

        $emailService->sendEmail($message);

        return true;
    }

    public function getLog(ActionConfig $actionConfig, $context)
    {
        return 'Pro prodejku č. '.$context['s_code'].' byla odeslána systémová zpráva.';
    }
}
