<?php

declare(strict_types=1);

namespace KupShop\GraphQLBundle\ApiShared\Types;

use KupShop\DropshipBundle\Util\DropshipmentUtil;
use KupShop\GraphQLBundle\ApiAdmin\Annotation\Module;
use KupShop\GraphQLBundle\ApiShared\ApiUtil;
use KupShop\GraphQLBundle\ApiShared\Types\DeliveryType\DeliveryMethod;
use KupShop\GraphQLBundle\ApiShared\Types\DeliveryType\PaymentMethod;
use KupShop\GraphQLBundle\ApiShared\Types\Order\OrderSource;
use KupShop\GraphQLBundle\ApiShared\Types\Order\OrderStatus;
use KupShop\GraphQLBundle\ApiShared\Types\Product\DeliveryTime;
use KupShop\GraphQLBundle\ApiShared\Types\Return\ReturnReason;
use KupShop\GraphQLBundle\ApiShared\Types\Return\ReturnStatus;
use KupShop\KupShopBundle\Config;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Functional\Mapping;
use KupShop\OrderingBundle\Util\Order\OrderInfo;
use KupShop\ReturnsBundle\Util\ReturnsUtil;
use TheCodingMachine\GraphQLite\Annotations\Field;
use TheCodingMachine\GraphQLite\Annotations\Type;

/**
 * Konfigurace e-shopu.
 *
 * @Type()
 */
class Configuration
{
    /**
     * Seznam stavů objednávek.
     *
     * @Field()
     *
     * @return OrderStatus[]
     */
    public function getOrderStatuses(): array
    {
        return ApiUtil::wrapItems(
            array_keys(getOrderStatuses()),
            OrderStatus::class
        );
    }

    /**
     * Seznam zdrojů objednávek.
     *
     * @Field()
     *
     * @return OrderSource[]
     */
    public function getOrderSources(): array
    {
        return ApiUtil::wrapItems(
            array_keys(OrderInfo::getOrderSources()),
            OrderSource::class
        );
    }

    /**
     * Seznam typů doprav.
     *
     * @Field()
     *
     * @return DeliveryMethod[]
     */
    public function getDeliveryTypes(): array
    {
        return ApiUtil::wrapItems(
            Mapping::mapKeys(\Delivery::listClasses(), fn ($k, $v) => [$k, ['type' => $k, 'name' => $v]]),
            PaymentMethod::class
        );
    }

    /**
     * Seznam typů plateb.
     *
     * @Field()
     *
     * @return PaymentMethod[]
     */
    public function getPaymentTypes(): array
    {
        return ApiUtil::wrapItems(
            Mapping::mapKeys(\Payment::listClasses(), fn ($k, $v) => [$k, ['type' => $k, 'name' => $v]]),
            PaymentMethod::class
        );
    }

    /**
     * @return DeliveryTime[]
     */
    #[Field(description: 'Dostupnosti zboží.')]
    public function getDeliveryTimes(): array
    {
        $cfg = Config::get();

        $deliveryTimes = [];
        foreach ($cfg['Products']['DeliveryTime'] ?? [] as $id => $_) {
            $deliveryTimes[] = new DeliveryTime((int) $id);
        }

        return $deliveryTimes;
    }

    /**
     * @return string[]
     */
    #[Field(description: 'Typy dropshipmentů.')]
    #[Module(\Modules::DROPSHIP)]
    public function getDropshipmentTypes(): array
    {
        return ServiceContainer::getService(DropshipmentUtil::class)->getDropshipmentTypes();
    }

    /**
     * @return iterable<ReturnStatus>
     */
    #[Field(description: 'Seznam stavů vratek.')]
    #[Module(\Modules::RETURNS)]
    public function getReturnStatuses(): iterable
    {
        foreach ($this->getReturnsUtil()->getStatuses() as $id => $name) {
            yield new ReturnStatus($id, $name);
        }
    }

    /**
     * @return iterable<ReturnReason>
     */
    #[Field(description: 'Seznam důvodů vrácení u vratek.')]
    #[Module(\Modules::RETURNS)]
    public function getReturnReasons(): iterable
    {
        foreach ($this->getReturnsUtil()->getReasons() as $id => $name) {
            yield new ReturnReason($id, $name);
        }
    }

    private function getReturnsUtil(): ReturnsUtil
    {
        static $returnsUtil;

        return $returnsUtil ??= ServiceContainer::getService(ReturnsUtil::class);
    }
}
