<?php

namespace Myvetshop\Module\Clinique\Import\Dixptz\Sync;

use Myvetshop\Module\Clinique\Import\Dixptz\Model\CustomerModel;
use Myvetshop\Module\Clinique\Import\Dixptz\Model\RewardModel;
use Myvetshop\Module\Clinique\Import\ImportFile\DispatchedCustomerData;
use Myvetshop\Module\Clinique\Import\Model\OrderModel;
use Myvetshop\Module\Clinique\Import\Sync\Syncer\AddressesSyncer;
use Myvetshop\Module\Clinique\Import\Sync\Syncer\CustomerSyncer;
use Myvetshop\Module\Clinique\Import\Sync\Syncer\OrdersSyncer;
use Myvetshop\Module\Clinique\Import\Sync\Syncer\RewardSyncer;
use Myvetshop\Module\Clinique\Import\Sync\SyncStatistics;

class DixptzDataSyncer
{
    protected AddressesSyncer $addressesSyncer;
    protected CustomerSyncer $customerSyncer;
    protected OrdersSyncer $ordersSyncer;

    protected RewardSyncer $rewardSyncer;

    public function __construct(
        AddressesSyncer $addressesSyncer,
        CustomerSyncer $customerSyncer,
        OrdersSyncer $ordersSyncer,
        RewardSyncer $rewardSyncer
    ) {
        $this->addressesSyncer = $addressesSyncer;
        $this->customerSyncer = $customerSyncer;
        $this->ordersSyncer = $ordersSyncer;
        $this->rewardSyncer = $rewardSyncer;
    }

    /**
     * @param array<string, \Clinique> $clinicMap
     */
    public function sync(array $clinicMap, DispatchedCustomerData $data, SyncStatistics $syncStatistics): void
    {
        $customerModel = $data->getCustomer(CustomerModel::class);
        \assert($customerModel instanceof CustomerModel);
        $clinique = $clinicMap[$customerModel->codePrivilege ?? ''] ?? null;

        if (!$clinique) {
            throw new \Exception(\sprintf('Clinic not found : %s', $customerModel->codePrivilege));
        }

        $customer = $this->customerSyncer->sync($syncStatistics, $clinique, $customerModel);
        $addressMap = $this->addressesSyncer->sync($syncStatistics, $customer, $data->getAdresses());
        $orders = $data->getOrders();
        \array_walk(
            $orders,
            function (OrderModel $orderModel) {
                $orderModel->reference = \substr($orderModel->reference, -8);
                $orderModel->idAddressDelivery = $orderModel->idAddressInvoice;
            }
        );

        $ordersMaps = $this->ordersSyncer->sync(
            $syncStatistics,
            $customer,
            $clinique,
            $addressMap,
            $orders,
            $data->getOrderDetails(),
            $data->getOrderDetailTaxes(),
        );

        $reward = $data->getReward(RewardModel::class);
        if ($reward) {
            $this->rewardSyncer->sync($customer, $reward);
        }
    }
}
