<?php

namespace EdgeBox\SyncCore\V2\Configuration;

use EdgeBox\SyncCore\Interfaces\Configuration\IConfigurationService;
use EdgeBox\SyncCore\Interfaces\IApplicationInterface;
use EdgeBox\SyncCore\V2\Raw\Model\FlowDeleteRequest;
use EdgeBox\SyncCore\V2\Raw\Model\FlowEntity;
use EdgeBox\SyncCore\V2\SyncCore;

class ConfigurationService implements IConfigurationService
{
    /**
     * @var SyncCore
     */
    protected $core;

    /**
     * SyndicationService constructor.
     */
    public function __construct(SyncCore $core)
    {
        $this->core = $core;
    }

    public function listRemoteFlows(string $remote_module_version)
    {
        return new ListRemoteFlows($this->core, $remote_module_version);
    }

    public function getRemoteFlow(string $id)
    {
        $request = $this
            ->core
            ->getClient()
            ->flowControllerItemRequest(id: $id)
        ;

        /**
         * @var FlowEntity $item
         */
        $item = $this
            ->core
            ->sendToSyncCoreAndExpect($request, FlowEntity::class, IApplicationInterface::SYNC_CORE_PERMISSIONS_CONFIGURATION, false, SyncCore::CONFIG_GET_RETRY_COUNT)
        ;

        return new RemoteFlowItem($this->core, $item);
    }

    public function defineFlow(string $machine_name, string $name, ?string $config)
    {
        return new DefineFlow($this->core, $machine_name, $name, $config);
    }

    public function defineLanguage(string $code, string $name)
    {
        return new DefineLanguage($this->core, code: $code, name: $name);
    }

    public function defineEntityType(?string $pool_id, string $type_machine_name, string $bundle_machine_name, string $version_id, ?string $name = null)
    {
        return new DefineEntityType($this->core, $type_machine_name, $bundle_machine_name, $version_id, $name);
    }

    public function defineTextProfile(string $machine_name, ?string $label = null)
    {
        return new DefineTextProfile($this->core, $machine_name, $label);
    }

    public function listRemotePools()
    {
        $request = $this
            ->core
            ->getClient()
            ->poolControllerListRequest()
        ;

        $response = $this
            ->core
            ->sendToSyncCore($request, IApplicationInterface::SYNC_CORE_PERMISSIONS_CONFIGURATION, false, SyncCore::CONFIG_GET_RETRY_COUNT)
        ;

        $remote_pools = json_decode($response, true);

        $options = [];
        foreach ($remote_pools as $option) {
            $machine_name = $option['machineName'];
            $options[$machine_name] = $option['name'];
        }

        return $options;
    }

    public function usePool(string $pool_id, string $pool_name)
    {
        return new RegisterPool($this->core, $pool_id, $pool_name);
    }

    public function enableEntityPreviews($public_access_possible = false)
    {
        // Not configurable by sites in the new Sync Core.
        return $this;
    }

    /**
     * @return $this
     */
    public function deleteFlows(array $keep_machine_names)
    {
        $dto = new FlowDeleteRequest();
        $dto->setKeepFlowMachineNames($keep_machine_names);

        $request = $this
            ->core
            ->getClient()
            ->flowControllerDeleteRequest(flowDeleteRequest: $dto)
        ;

        $this
            ->core
            ->sendToSyncCore($request, IApplicationInterface::SYNC_CORE_PERMISSIONS_CONFIGURATION, false, SyncCore::CONFIG_EXPORT_RETRY_COUNT)
        ;

        return $this;
    }
}
