<?php

declare(strict_types=1);

namespace KupShop\KupShopBundle\Util;

/**
 * Pro přidávání dat (zdroj pohybu, admin) do záznamu pohybů na skladě.
 * Používá jak warehouse, tak stores.
 */
class LoggingContext
{
    public const TYPE_ORDER = 'orders';
    public const TYPE_TRANSFER = 'storesTransfers';
    public const TYPE_STOCK_IN = 'stockIn';
    public const TYPE_EDIT = 'edit';
    public const TYPE_API = 'api';
    public const TYPE_AUTOMATIC_IMPORT = 'automatic_import';

    protected ?int $id_user = null;
    protected ?int $id_order = null;
    protected ?int $id_transfer = null;
    protected ?int $id_stock_in = null;
    protected ?int $id_automatic_import = null;
    protected ?string $object_type = null;

    public function activateOrder(int $id_order, callable $callback)
    {
        return $this->activate(self::TYPE_ORDER, $id_order, $callback);
    }

    public function activateStoreTransfer(int $id_transfer, callable $callback)
    {
        return $this->activate(self::TYPE_TRANSFER, $id_transfer, $callback);
    }

    public function activateStockIn(int $id_stock_in, callable $callback)
    {
        return $this->activate(self::TYPE_STOCK_IN, $id_stock_in, $callback);
    }

    public function activateEdit(callable $callback)
    {
        return $this->activateTypeOnly(self::TYPE_EDIT, $callback);
    }

    public function activateApi(callable $callback)
    {
        return $this->activateTypeOnly(self::TYPE_API, $callback);
    }

    public function activateAutomaticImport(?int $id_auto_import, callable $callback)
    {
        if ($id_auto_import) {
            return $this->activate(self::TYPE_AUTOMATIC_IMPORT, $id_auto_import, $callback);
        }

        return $this->activateTypeOnly(self::TYPE_AUTOMATIC_IMPORT, $callback);
    }

    public function activateTypeOnly(string $type, callable $callback)
    {
        $original_type = $this->getObjectType();
        $this->setObjectType($type);

        $return = $callback();

        $this->setObjectType($original_type);

        return $return;
    }

    public function activateUser(int $id_user, callable $callback)
    {
        $orig_user = $this->getIdUser();
        if ($id_user) {
            $this->setIdUser($id_user);
        }

        $return = $callback();

        $this->setIdUser($orig_user);

        return $return;
    }

    public function activate(string $type, int $id_object, callable $callback)
    {
        $getter = 'getId'.ucfirst($type);
        $setter = 'setId'.ucfirst($type);
        $original_id = $this->{$getter}();
        $original_type = $this->getObjectType();

        if ($id_object) {
            $this->{$setter}($id_object);
        }
        $this->setObjectType($type);

        $return = $callback();

        $this->{$setter}($original_id);
        $this->setObjectType($original_type);

        return $return;
    }

    public function getIdUser(): ?int
    {
        return $this->id_user;
    }

    public function setIdUser(?int $id_user): static
    {
        $this->id_user = $id_user;

        return $this;
    }

    public function getIdOrders(): ?int
    {
        return $this->id_order;
    }

    public function setIdOrders(?int $id_order): static
    {
        $this->id_order = $id_order;

        return $this;
    }

    public function getIdStoresTransfers(): ?int
    {
        return $this->id_transfer;
    }

    public function setIdStoresTransfers(?int $id_transfer): static
    {
        $this->id_transfer = $id_transfer;

        return $this;
    }

    public function getIdStockIn(): ?int
    {
        return $this->id_stock_in;
    }

    public function setIdStockIn(?int $id_stock_in): static
    {
        $this->id_stock_in = $id_stock_in;

        return $this;
    }

    public function getObjectType(): ?string
    {
        return $this->object_type;
    }

    public function setObjectType(?string $object_type): void
    {
        $this->object_type = $object_type;
    }

    public function getIdAutomatic_import(): ?int
    {
        return $this->id_automatic_import;
    }

    public function setIdAutomatic_import(?int $id_auto_import): void
    {
        $this->id_automatic_import = $id_auto_import;
    }

    /** Return single ID */
    public function getObjectId(): ?int
    {
        if ($this->getObjectType()) {
            $getter = 'getId'.ucfirst($this->getObjectType());
            if (method_exists($this, $getter)) {
                return $this->{$getter}();
            }
        }

        return null;
    }
}
