<?php

namespace KupShop\AutomationConfiguratorBundle\Configurator\Orders\Actions;

use KupShop\AutomationConfiguratorBundle\Configurator\Interfaces\Config\ActionConfig;
use KupShop\AutomationConfiguratorBundle\Configurator\Orders\OrdersContext;
use KupShop\AutomationConfiguratorBundle\Configurator\Orders\Triggers\OrderCreated;
use KupShop\AutomationConfiguratorBundle\Event\TriggerEvent;
use KupShop\AutomationConfiguratorBundle\Exceptions\ActionRuntimeException;
use KupShop\AutomationConfiguratorBundle\Util\ActionUtil;
use KupShop\KupShopBundle\Context\ContextManager;
use KupShop\KupShopBundle\Email\OrderMessageEmail;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\Logging\CustomDataExceptionInterface;
use KupShop\KupShopBundle\Util\Logging\SentryLogger;
use KupShop\KupShopBundle\Util\Mail\SMSSender;
use Symfony\Contracts\Service\Attribute\Required;

class SendEmail extends Action implements OrdersContext
{
    public const NAME = 'send_email';

    #[Required]
    public SentryLogger $sentryLogger;

    /**
     * @var OrderMessageEmail
     */
    protected $emailService;

    #[Required]
    public ActionUtil $actionUtil;

    /**
     * @required
     */
    public function setEmailService(OrderMessageEmail $emailService): void
    {
        $this->emailService = $emailService;
    }

    public function getConfig()
    {
        $statuses = [];

        $orderMessages = $this->emailService->getOrderMessages();

        $statuses[] = ['key' => '-', 'title' => 'Zvolte zprávu'];

        foreach ($orderMessages as $message) {
            $statuses[] = ['key' => (string) $message['name'], 'title' => $message['name']];
        }

        return [
            'label' => 'Odeslat uživatelskou zprávu',
            'fields' => [
                [
                    'name' => 'order_message_id',
                    'title' => 'Typ zprávy',
                    'type' => 'select',
                    'values' => $statuses,
                ],
                [
                    'name' => 'send_to_invoice_email',
                    'title' => 'Odeslat i na email pro fakturaci',
                    'type' => 'checkbox',
                ],
            ],
        ];
    }

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

    public function run(ActionConfig $actionConfig, $context, TriggerEvent $triggerEvent): bool
    {
        $messageId = $actionConfig->getField('order_message_id')->getValue();
        $sendToInvoiceEmail = $actionConfig->getField('send_to_invoice_email')?->getValue() === 'Y';

        if (!$messageId || $messageId == '-') {
            return false;
        }

        try {
            $order = $this->actionUtil->getOrder($context['id'], $triggerEvent);
            $contextManager = Contexts::get(ContextManager::class);

            $contextManager->activateOrder($order, function () use ($order, $messageId, $triggerEvent, $sendToInvoiceEmail) {
                $this->emailService->setOrder($order);
                $this->emailService->setOrderMessage($messageId);
                $this->emailService->setIsAdminEmail(false);
                $emailTemplate = $this->emailService->getEmailTemplate();

                $emailName = $emailTemplate['name'];
                $body = $emailTemplate['body'];

                $action = function () use ($order, $body, $emailName, $sendToInvoiceEmail) {
                    $order->sendEmail($body, $emailName, sendToInvoiceEmail: $sendToInvoiceEmail);
                    $order->logHistory('Autopilot: odeslána uživatelská zpráva: '.$emailName);
                    $SMSSender = ServiceContainer::getService(SMSSender::class);
                    $SMSSender->sendSMS($order, $this->emailService, force_order_history: true);
                };

                if ($triggerEvent->getTriggerName() == OrderCreated::NAME) {
                    $this->postOrderFinishedRunner->registerCallback($action);
                } else {
                    $action();
                }
            });
        } catch (\Exception $e) {
            // chci to i do sentry, at vime o tom, ze se stalo neco spatne
            $this->sentryLogger->captureException($e);

            throw new ActionRuntimeException(
                "Pro objednávku č. {$context['o_order_no']} nebyla odeslána uživatelská zpráva.",
                [
                    'type' => $messageId,
                    // pridam i data o ty predesly exceptione, at to aspon neco rekne...
                    'originalException' => $e->getMessage(),
                    'originalData' => $e instanceof CustomDataExceptionInterface ? $e->getData() : [],
                ]
            );
        }

        return true;
    }

    public function getLog(ActionConfig $actionConfig, $context)
    {
        return 'Pro objednávku č. '.$context['o_order_no'].' byla odeslána uživatelská zpráva.';
    }
}
