<?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\Carrier\Adapter;

use Address;
use Country;
use Db;
use Module;
use PrestaShopLogger;
use SimplyIn\Carrier\AbstractCarrierAdapter;
use SimplyIn\Carrier\PointData;
use Throwable;

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

final class DhlAdapter extends AbstractCarrierAdapter
{
    private const DHLA_TABLE = 'dhla_sourceorderadditionalparams';
    private const SENSBIT_TABLE = 'sensbitdhl_cart';

    public function __construct(
        Db $db,
        private readonly ApaczkaAdapter $apaczka,
    ) {
        parent::__construct($db);
    }

    public function supportedLabels(): array
    {
        return ['dhl'];
    }

    public function setPoint(int $idCart, PointData $point): void
    {
        $this->apaczka->setPoint($idCart, $point);
        foreach ($this->apaczka->drainWarnings() as $warning) {
            $this->addWarning($warning);
        }
        $this->setDhlAssistant($idCart, $point);
        $this->setSensbitDhl($idCart, $point);
    }

    public function clearPoint(int $idCart): void
    {
        $this->apaczka->clearPoint($idCart);
        foreach ($this->apaczka->drainWarnings() as $warning) {
            $this->addWarning($warning);
        }
        $this->clearDhlAssistant($idCart);
        $this->clearSensbitDhl($idCart);
    }

    private function setDhlAssistant(int $idCart, PointData $point): void
    {
        if (!Module::isInstalled('dhlassistant')) {
            return;
        }

        $deliveryAddress = new Address($this->resolveDeliveryAddressId($idCart));
        $country = new Country((int) $deliveryAddress->id_country);
        $countryCode = $country->iso_code ?: 'PL';

        $isParcelLocker = $point->serviceType === 'parcel_machine';
        $postalCode = '';
        if ($point->address !== null && preg_match('/(\d{2}-\d{3})/', $point->address, $matches)) {
            $postalCode = str_replace('-', '', $matches[1]);
        }

        $this->safeExecute('DELETE FROM `' . _DB_PREFIX_ . self::DHLA_TABLE . '` WHERE `IdSourceObject` = ' . $idCart);
        $sql = 'INSERT INTO `' . _DB_PREFIX_ . self::DHLA_TABLE . '` '
            . '(`IdSourceObject`, `CountryCode`, `SendToParcelShop`, `SendToParcelLocker`, `ParcelIdent`, `Postnummer`, `ParcelPostalCode`) '
            . 'VALUES ('
            . $idCart . ', '
            . '"' . pSQL($countryCode) . '", '
            . ($isParcelLocker ? 0 : 1) . ', '
            . ($isParcelLocker ? 1 : 0) . ', '
            . '"' . pSQL($point->lockerId) . '", '
            . '"", '
            . '"' . pSQL($postalCode) . '"'
            . ')';

        try {
            $this->db->execute($sql);
        } catch (Throwable $e) {
            PrestaShopLogger::addLog('SimplyIn DHL adapter insert failed: ' . $e->getMessage(), 2, null, 'SimplyIn');
            $this->addWarning($e->getMessage());
        }
    }

    private function clearDhlAssistant(int $idCart): void
    {
        if (!Module::isInstalled('dhlassistant')) {
            return;
        }
        $this->safeExecute('DELETE FROM `' . _DB_PREFIX_ . self::DHLA_TABLE . '` WHERE `IdSourceObject` = ' . $idCart);
    }

    private function setSensbitDhl(int $idCart, PointData $point): void
    {
        if (!Module::isInstalled('sensbitdhl')) {
            return;
        }
        $lockerId = pSQL($point->lockerId);
        $this->safeExecute('DELETE FROM `' . _DB_PREFIX_ . self::SENSBIT_TABLE . '` WHERE `id_cart` = ' . $idCart);
        $this->safeExecute(
            'INSERT INTO `' . _DB_PREFIX_ . self::SENSBIT_TABLE . '` (`id_cart`, `id_point`, `date_add`, `date_upd`) '
            . 'VALUES (' . $idCart . ', "' . $lockerId . '", NOW(), NOW())',
        );
    }

    private function clearSensbitDhl(int $idCart): void
    {
        if (!Module::isInstalled('sensbitdhl')) {
            return;
        }
        $this->safeExecute('DELETE FROM `' . _DB_PREFIX_ . self::SENSBIT_TABLE . '` WHERE `id_cart` = ' . $idCart);
    }

    private function resolveDeliveryAddressId(int $idCart): int
    {
        $row = $this->db->getRow('SELECT `id_address_delivery` FROM `' . _DB_PREFIX_ . 'cart` WHERE `id_cart` = ' . $idCart);

        return isset($row['id_address_delivery']) ? (int) $row['id_address_delivery'] : 0;
    }
}
