<?php

/**
 * Copyright 2024-2025 Simply.IN Sp. z o.o.
 *
 * NOTICE OF LICENSE
 *
 * Licensed under the EUPL-1.2 or later.
 * You may not use this work except in compliance with the Licence.
 *
 * Copy of the Licence is available at:
 * https://joinup.ec.europa.eu/software/page/eupl
 * It is bundled with this package in the file LICENSE.txt
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the Licence is distributed on an as is basis,
 * without warranties or conditions of any kind, either express or implied.
 * Check the Licence for the specific language governing permissions
 * and limitations under the License.
 *
 * @author   Simply.IN Sp. z o.o.
 * @copyright 2024-2025 Simply.IN Sp. z o.o.
 * @license   https://joinup.ec.europa.eu/software/page/eupl
 */

declare(strict_types=1);

namespace SimplyIn\Ajax\Service;

use Configuration;
use SimplyIn\Carrier\CarrierAdapterRegistry;
use SimplyIn\Carrier\CartCarrierSetter;
use SimplyIn\Carrier\PointData;
use SimplyInPoint;

if (!defined('_PS_VERSION_')) {
    exit;
}

final class CarrierPointService
{
    public function __construct(
        private readonly CarrierAdapterRegistry $registry,
        private readonly CartCarrierSetter $carrierSetter,
    ) {
    }

    /**
     * @param array{
     *     providerId?: string,
     *     providerName?: string,
     *     service_type?: string,
     *     addressName?: string,
     *     address?: string,
     *     lockerId?: string
     * } $pointData
     *
     * @return list<string> warnings bubbled from adapters
     */
    public function selectPoint(int $idCart, array $pointData): array
    {
        $point = SimplyInPoint::getByIdCart($idCart);
        $point->providerId = (string) ($pointData['providerId'] ?? '');
        $point->service_type = (string) ($pointData['service_type'] ?? '');
        $point->addressName = (string) ($pointData['addressName'] ?? '');
        $point->address = (string) ($pointData['address'] ?? '');
        $point->label = (string) ($pointData['providerName'] ?? '');
        $point->lockerId = (string) ($pointData['lockerId'] ?? '');
        $point->save();

        $adapter = $this->registry->getAdapter((string) $point->label);
        if ($adapter === null) {
            return [];
        }

        $this->applyConfiguredCarrier((string) $point->label);
        $adapter->setPoint($idCart, PointData::fromObject($point));

        return $adapter->drainWarnings();
    }

    /**
     * @return list<string>
     */
    public function clearPoint(int $idCart): array
    {
        $point = SimplyInPoint::getByIdCart($idCart);
        if (!$point->id) {
            $this->applyConfiguredCarrier('default');

            return [];
        }

        $adapter = $this->registry->getAdapter((string) $point->label);
        $warnings = [];
        if ($adapter !== null) {
            $adapter->clearPoint($idCart);
            $warnings = $adapter->drainWarnings();
        }
        $point->delete();
        $this->applyConfiguredCarrier('default');

        return $warnings;
    }

    private function applyConfiguredCarrier(string $label): void
    {
        $configKey = match ($label) {
            'inpost' => 'SIMPLYIN_INPOST_CARRIER_ID',
            'dhl' => 'SIMPLYIN_DHL_CARRIER_ID',
            'dpd' => 'SIMPLYIN_DPD_CARRIER_ID',
            'orlen' => 'SIMPLYIN_ORLEN_CARRIER_ID',
            'fedex' => 'SIMPLYIN_FEDEX_CARRIER_ID',
            'ups' => 'SIMPLYIN_UPS_CARRIER_ID',
            default => 'SIMPLYIN_DEFAULT_CARRIER_ID',
        };
        $idCarrier = (int) Configuration::get($configKey);
        if ($idCarrier > 0) {
            $this->carrierSetter->apply($idCarrier);
        }
    }
}
