<?php

namespace Shop;


use Core\Console\Application;
use Core\Contracts\ServiceProviderInterface;

use Core\Template\Template;
use Diamond\Config\Main;


use League\Container\ServiceProvider\AbstractServiceProvider;
use League\Container\ServiceProvider\BootableServiceProviderInterface;


use Psr\Container\ContainerInterface;
use Shop\Application\Analytics\CreateTransaction\CreateTransactionCommand;
use Shop\Application\Analytics\CreateTransaction\CreateTransactionHandler;
use Shop\Application\Catalog\CatalogService;
use Shop\Application\Notification\SendEmail\SendEmailCommand;
use Shop\Application\Notification\SendEmail\SendEmailHandler;
use Shop\Application\Office\AuthCustomer\AuthCustomerCommand;
use Shop\Application\Office\AuthCustomer\AuthCustomerHandler;
use Shop\Application\Office\ChangeCustomerPassword\ChangeCustomerPasswordCommand;
use Shop\Application\Office\ChangeCustomerPassword\ChangeCustomerPasswordHandler;
use Shop\Application\Office\CreateDealer\CreateDealerCommand;
use Shop\Application\Office\CreateDealer\CreateDealerHandler;
use Shop\Application\Office\CustomerRegistration\CustomerRegistrationCommand;
use Shop\Application\Office\CustomerRegistration\CustomerRegistrationHandler;
use Shop\Application\Office\SendNotifyCustomerPassword\SendNotifyCustomerPasswordCommand;
use Shop\Application\Office\SendNotifyCustomerPassword\SendNotifyCustomerPasswordHandler;
use Shop\Application\Office\SendNotifyCustomerRegistration\SendNotifyCustomerRegistrationCommand;
use Shop\Application\Office\SendNotifyCustomerRegistration\SendNotifyCustomerRegistrationHandler;
use Shop\Application\Shopping\ChangeOrderItemState\ChangeOrderItemStateCommand;
use Shop\Application\Shopping\ChangeOrderItemState\ChangeOrderItemStateHandler;
use Shop\Application\Shopping\ChangeOrderState\ChangeOrderStateCommand;
use Shop\Application\Shopping\ChangeOrderState\ChangeOrderStateHandler;
use Shop\Application\Shopping\CreateCustomerOrder\CreateCustomerOrderCommand;
use Shop\Application\Shopping\CreateCustomerOrder\CreateCustomerOrderHandler;

use Shop\Application\Shopping\CreateFileFromOrderItems\CreateFileFromOrderItemsCommand;
use Shop\Application\Shopping\CreateFileFromOrderItems\CreateFileFromOrderItemsHandler;
use Shop\Application\Shopping\CreateProviderOrder\CreateProviderOrderHandler;
use Shop\Application\Shopping\CreateProviderOrdersFromCustomerOrderItem\CreateProviderOrdersFromCustomerOrderItemCommand;
use Shop\Application\Shopping\CreateProviderOrdersFromCustomerOrderItem\CreateProviderOrdersFromCustomerOrderItemHandler;
use Shop\Application\Shopping\MergeCustomerOrders\MergeCustomerOrdersCommand;
use Shop\Application\Shopping\MergeCustomerOrders\MergeCustomerOrdersHandler;
use Shop\Application\Shopping\MergeProducts\MergeProductsCommand;
use Shop\Application\Shopping\MergeProducts\MergeProductsHandler;
use Shop\Application\Shopping\MergeProviderOrders\MergeProviderOrdersCommand;
use Shop\Application\Shopping\MergeProviderOrders\MergeProviderOrdersHandler;
use Shop\Application\Shopping\PrepareCustomerOrderDataForReport\PrepareCustomerOrderDataForReportCommand;
use Shop\Application\Shopping\PrepareCustomerOrderDataForReport\PrepareCustomerOrderDataForReportHandler;
use Shop\Application\Shopping\PrepareProviderOrderDataForReport\PrepareProviderOrderDataForReportCommand;
use Shop\Application\Shopping\PrepareProviderOrderDataForReport\PrepareProviderOrderDataForReportHandler;
use Shop\Application\Shopping\ResetOrderState\ResetOrderStateCommand;
use Shop\Application\Shopping\ResetOrderState\ResetOrderStateHandler;
use Shop\Application\Shopping\SendCustomerOrders\SendCustomerOrdersCommand;
use Shop\Application\Shopping\SendCustomerOrders\SendCustomerOrdersHandler;
use Shop\Application\Shopping\SendNotifyAboutPostCode\SendNotifyAboutPostCodeCommand;
use Shop\Application\Shopping\SendNotifyAboutPostCode\SendNotifyAboutPostCodeHandler;
use Shop\Application\Shopping\SendNotifyAboutState\SendNotifyAboutStateCommand;
use Shop\Application\Shopping\SendNotifyAboutState\SendNotifyAboutStateHandler;
use Shop\Application\Shopping\SendNotifyOrderChangeState\SendNotifyOrderChangeStateCommand;
use Shop\Application\Shopping\SendNotifyOrderChangeState\SendNotifyOrderChangeStateHandler;
use Shop\Application\Shopping\SendProviderOrders\SendProviderOrdersCommand;
use Shop\Application\Shopping\SendProviderOrders\SendProviderOrdersHandler;
use Shop\Commands\Sitemap;
use Shop\Controllers\CityController;
use Shop\Controllers\OrderController;
use Shop\Controllers\RegionController;
use Shop\Controllers\StateController;
use Shop\Controllers\StockController;
use Shop\Domain\Brand\Contracts\BrandRepositoryInterface;
use Shop\Domain\Product\Contracts\ProductRepositoryInterface;
use Shop\Domain\Product\Contracts\ProductThumbCreaterInterface;
use Shop\Domain\Product\ProductService;
use Shop\Domain\ProductCategory\Contracts\ProductCategoryRepositoryInterface;


use Shop\Application\Basket\AddItemInCurrentBasket\AddItemInCurrentBasketCommand;
use Shop\Application\Basket\AddItemInCurrentBasket\AddItemInCurrentBasketHandler;
use Shop\Modules\AdminOrderItems\CreateProviderOrderCommand;
use Shop\Repositories\Brand\BrandRepository;
use Shop\Repositories\Product\ProductRepository;
use Shop\Repositories\ProductCategory\ProductCategoryRepository;


use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Twig\Environment;


/**
 * Description of SystemServiceProvider
 *
 * @author Dmitriy
 */
class ServiceProvider extends AbstractServiceProvider implements ServiceProviderInterface
{

    protected $provides = [
        \Core\Basket\Basket::class,
        BrandRepositoryInterface::class,
        ProductCategoryRepositoryInterface::class,
        ProductRepositoryInterface::class,
        ProductThumbCreaterInterface::class
    ];

    /**
     * @return array
     */
    public static function getCommandBusMap(): array
    {
        return [
            //Analitic
            CreateTransactionCommand::class => [CreateTransactionHandler::class, 'handle'],

            //Basket
            AddItemInCurrentBasketCommand::class => [AddItemInCurrentBasketHandler::class, 'handle'],

            //Office
            AuthCustomerCommand::class => [AuthCustomerHandler::class, 'handle'],
            CustomerRegistrationCommand::class => [CustomerRegistrationHandler::class, 'handle'],
            ChangeCustomerPasswordCommand::class => [ChangeCustomerPasswordHandler::class, 'handle'],
            SendNotifyCustomerPasswordCommand::class => [SendNotifyCustomerPasswordHandler::class, 'handle'],
            SendNotifyCustomerRegistrationCommand::class => [SendNotifyCustomerRegistrationHandler::class, 'handle'],
            CreateDealerCommand::class => [CreateDealerHandler::class, 'handle'],
            //Shopping
            ChangeOrderItemStateCommand::class => [ChangeOrderItemStateHandler::class, 'handle'],
            ChangeOrderStateCommand::class => [ChangeOrderStateHandler::class, 'handle'],

            CreateCustomerOrderCommand::class => [CreateCustomerOrderHandler::class, 'handle'],
            CreateFileFromOrderItemsCommand::class => [CreateFileFromOrderItemsHandler::class, 'handle'],
            CreateProviderOrderCommand::class => [CreateProviderOrderHandler::class, 'handle'],
            CreateProviderOrdersFromCustomerOrderItemCommand::class => [CreateProviderOrdersFromCustomerOrderItemHandler::class, 'handle'],
            MergeCustomerOrdersCommand::class => [MergeCustomerOrdersHandler::class, 'handle'],
            MergeProductsCommand::class => [MergeProductsHandler::class, 'handle'],
            MergeProviderOrdersCommand::class => [MergeProviderOrdersHandler::class, 'handle'],
            PrepareCustomerOrderDataForReportCommand::class => [PrepareCustomerOrderDataForReportHandler::class, 'handle'],
            PrepareProviderOrderDataForReportCommand::class => [PrepareProviderOrderDataForReportHandler::class, 'handle'],
            ResetOrderStateCommand::class => [ResetOrderStateHandler::class, 'handle'],
            SendCustomerOrdersCommand::class => [SendCustomerOrdersHandler::class, 'handle'],
            SendNotifyAboutPostCodeCommand::class => [SendNotifyAboutPostCodeHandler::class, 'handle'],
            SendNotifyAboutStateCommand::class => [SendNotifyAboutStateHandler::class, 'handle'],
            SendNotifyOrderChangeStateCommand::class => [SendNotifyOrderChangeStateHandler::class, 'handle'],
            SendProviderOrdersCommand::class => [SendProviderOrdersHandler::class, 'handle'],
            \Shop\Application\Payment\CreateTransaction\CreateTransactionCommand::class => [\Shop\Application\Payment\CreateTransaction\CreateTransactionHandler::class,'handle']
        ];
    }


    public function register()
    {
        $di = $this->getContainer();

        $di->add(BrandRepositoryInterface::class, BrandRepository::class);
        $di->add(ProductCategoryRepositoryInterface::class, ProductCategoryRepository::class);
        $di->add(ProductRepositoryInterface::class, ProductRepository::class);


        $di->share(ProductThumbCreaterInterface::class, function () use ($di) {
            return $di->get(CatalogService::class);
        });

        /**
         * set Debug bar
         */
        $di->add(Session::class, function () use ($di) {
            $lifetime = $di->get(Main::class)->getSessionLife();
            if (!$lifetime) {
                $lifetime = 1;//час
            }
            session_set_cookie_params($lifetime * 60 * 60);

            return new Session(
                new NativeSessionStorage([
                    //"cache_expire" => $lifetime*10*60*60,
                    // "cookie_domain"=>   Url::createQookieMainDomain(),
                    'cookie_lifetime' => $lifetime * 60 * 60,
                    'gc_maxlifetime' => $lifetime * 60 * 60
                ])
            );
        }, true);

        $di->add(\Core\Basket\Basket::class, null, true)
            ->addArgument($di->get(Session::class));


    }

    /**
     * @return string
     */
    public static function getPackageName(): string
    {
        return 'shop';
    }

    /**
     * @return string
     */
    public static function getViewsPath(): string
    {
        return __DIR__ . '/Views/';
    }

    /**
     * @return array
     */
    public static function getRoutes(): array
    {
        return [
            [['GET', 'POST'], '/_service/shop/cities', [CityController::class, 'index']],
            [['GET', 'POST'], '/_service/shop/regions', [RegionController::class, 'index']],
            [['GET'], '/_service/shop/stocks', [StockController::class, 'index']],
            [['GET'], '/_service/shop/order/{id}/state/image', [OrderController::class, 'stateImage']],
            [['GET'], '/_service/shop/order/aggregate_sum_day', [OrderController::class, 'aggregateSumDay']]
        ];
    }


    public function afterInit(ContainerInterface $container): void
    {
        $container
            ->get(Environment::class)
            ->addExtension(
                new TwigExtension()
            );


        //
        $container
            ->get(Application::class)
            ->add(
                $container->get(Sitemap::class)
            );

        /**
         * @var Template $template
         */
        $container->get(Template::class)->addStyleLink('/_diamond/shop/assets/css/custom.css');
    }

}
