<?php

declare(strict_types=1);

namespace KupShop\DropshipBundle\Util;

use KupShop\AdminBundle\Util\ActivityLog;
use KupShop\DropshipBundle\Exception\TransferException;
use KupShop\DropshipBundle\TransferInterface;
use KupShop\KupShopBundle\Util\Logging\SentryLogger;
use Query\Operator;

class TransferWorker
{
    protected TransferLocator $transferLocator;
    protected DropshipmentUtil $dropshipmentUtil;

    private SentryLogger $sentryLogger;

    public function __construct(DropshipmentUtil $dropshipmentUtil, TransferLocator $transferLocator, SentryLogger $sentryLogger)
    {
        $this->dropshipmentUtil = $dropshipmentUtil;
        $this->transferLocator = $transferLocator;
        $this->sentryLogger = $sentryLogger;
    }

    public function run(?int $id = null): void
    {
        $dropshipments = $id ? [$this->dropshipmentUtil->getDropshipment($id)] : $this->dropshipmentUtil->getDropshipments();

        foreach ($dropshipments as $dropshipment) {
            $transfer = $this->transferLocator->getTransfer($dropshipment['type']);
            $transfer->setup($dropshipment);

            // preskocim dropshipmenty, ktere se nemaji spoustet
            if (!$transfer->isRunnable()) {
                continue;
            }

            try {
                $newLastSyncTime = date('Y-m-d H:i:s');
                $transfer->process();
                $this->updateLastSyncTime($newLastSyncTime, $transfer);
            } catch (\Throwable $e) {
                $this->logException($e, $transfer);
            }
        }
    }

    public function logException(\Throwable $e, TransferInterface $transfer): void
    {
        if (isLocalDevelopment()) {
            throw $e;
        }

        $message = sprintf('[Dropshipment] Chyba během zpracování: %s (ID: %s)', $transfer->dropshipment['name'], $transfer->dropshipment['id']);

        $data = ['error' => $e->getMessage()];
        if (!($e instanceof TransferException)) {
            $this->sentryLogger->captureException($e);
        } else {
            $message = $e->getMessage();
            $data = array_merge($data, $e->getData());
        }

        addActivityLog(
            ActivityLog::SEVERITY_ERROR,
            ActivityLog::TYPE_IMPORT,
            $message,
            $data
        );
    }

    protected function updateLastSyncTime(string $lastSyncTime, TransferInterface $transfer): void
    {
        sqlQueryBuilder()
            ->update('dropshipment')
            ->directValues(['last_sync' => $lastSyncTime])
            ->where(Operator::equals(['id' => $transfer->dropshipment['id']]))
            ->execute();
    }
}
