<?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\Checkout;

use AddressChecksum;
use CartChecksum;
use Context;
use Db;
use SimplyIn\Front\OpcDetector;
use SimplyIn\Session\SimplyInSessionInterface;
use Tools;

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

class CheckoutSessionRepository
{
    private SimplyInSessionInterface $session;

    private OpcDetector $opcDetector;

    public function __construct(SimplyInSessionInterface $session, OpcDetector $opcDetector)
    {
        $this->session = $session;
        $this->opcDetector = $opcDetector;
    }

    public function updateDeliveryAddress(int $idAddressDelivery, int $idCart): void
    {
        $db = Db::getInstance();
        $db->execute(
            'UPDATE `' . _DB_PREFIX_ . 'cart_product`'
            . ' SET id_address_delivery = ' . $idAddressDelivery
            . ' WHERE id_cart = ' . $idCart,
        );
        $db->execute(
            'UPDATE `' . _DB_PREFIX_ . 'customization`'
            . ' SET id_address_delivery = ' . $idAddressDelivery
            . ' WHERE id_cart = ' . $idCart,
        );
    }

    /**
     * @return null|array<string, mixed>
     */
    public function getCheckoutSessionData(int $idCart): ?array
    {
        $raw = Db::getInstance()->getValue(
            'SELECT checkout_session_data FROM `' . _DB_PREFIX_ . 'cart` WHERE id_cart = ' . $idCart,
        );

        if (!is_string($raw) || $raw === '') {
            return null;
        }

        $decoded = json_decode($raw, true);

        return is_array($decoded) ? $decoded : null;
    }

    public function upgradeSessionData(Context $context, bool $redirect = true): void
    {
        $cart = $context->cart;
        if ($cart === null) {
            return;
        }

        if ($this->opcDetector->detect() === OpcDetector::OPC_THECHECKOUT) {
            $context->cookie->addreses_reset_at_cart_id = $cart->id;
            $context->cookie->write();
        }

        $idAddressInvoice = $this->session->get('simplyin_id_address_invoice');
        $idAddressDelivery = $this->session->get('simplyin_id_address_delivery');

        if (empty($idAddressInvoice) || empty($idAddressDelivery)) {
            return;
        }

        $data = [
            'checkout-personal-information-step' => [
                'step_is_reachable' => 1,
                'step_is_complete' => 1,
            ],
            'checkout-addresses-step' => [
                'step_is_reachable' => 1,
                'step_is_complete' => 1,
                'use_same_address' => (int) ($idAddressInvoice == $idAddressDelivery),
            ],
            'checkout-delivery-step' => [
                'step_is_reachable' => 1,
                'step_is_complete' => 1,
            ],
            'checkout-payment-step' => [
                'step_is_reachable' => 1,
                'step_is_complete' => 0,
            ],
        ];
        $data['checksum'] = (new CartChecksum(new AddressChecksum()))->generateChecksum($cart);

        $existing = $this->getCheckoutSessionData((int) $cart->id);
        if (is_array($existing) && isset($existing['simplyin'])) {
            $data['simplyin'] = $existing['simplyin'];
        }

        Db::getInstance()->execute(
            'UPDATE `' . _DB_PREFIX_ . 'cart`'
            . " SET checkout_session_data = '" . pSQL(json_encode($data)) . "'"
            . ' WHERE id_cart = ' . (int) $cart->id,
        );

        if ($redirect) {
            Tools::redirect($context->link->getPageLink('order', true, null));
        }
    }
}
