<?php

namespace Opencart\Catalog\Controller\Extension\Alsendo\Event;

require_once(DIR_EXTENSION . 'alsendo/src/DTO/Entity/AlsendoRegionEntity.php');
require_once(DIR_EXTENSION . 'alsendo/src/OrderDetails/CreateOrderDetailsFactory.php');

use Opencart\Extension\Alsendo\DTO\Entity\AlsendoRegionEntity;
use Opencart\Extension\Alsendo\OrderDetails\CreateOrderDetailsFactory;

class Checkout extends \Opencart\System\Engine\Controller
{
    private ?AlsendoRegionEntity $currentRegion = null;

    public function __construct($registry)
    {
        parent::__construct($registry);

        $this->load->model('extension/alsendo/module/alsendo_region');
        $this->currentRegion = $this->model_extension_alsendo_module_alsendo_region->getCurrentRegion();
    }

    public function saveSelectedPoint(string $route, array &$data, ?int $orderId): void
    {
        if (empty($orderId)) {
            return;
        }

        $this->session->data['current_order_id'] = $orderId;

        $selectedPickupPointData = $this->session->data['alsendo_pickup_point'] ?? null;
        if (empty($selectedPickupPointData)) {
            return;
        }

        $pickupPointToSave = json_decode(html_entity_decode($selectedPickupPointData), true);
        $pickupPointToSave = json_encode($pickupPointToSave);

        $this->db->query("
            INSERT INTO `" . DB_PREFIX . "alsendo_order_pickup_points`
                SET order_id = '" . $orderId . "',
                    pickup_point = '" . $this->db->escape($pickupPointToSave) . "'
            ON DUPLICATE KEY UPDATE pickup_point = VALUES(pickup_point)
        ");
    }

    public function createAlsendoOrderDetails(string $route, array &$data): void
    {
        $orderId = $this->session->data['current_order_id'] ?? null;

        if (!$orderId || $this->currentRegion === null) {
            return;
        }

        try {
            $factory = new CreateOrderDetailsFactory($this->registry);
            $createOrderDetails = $factory->getCreateOrderDetailsForRegion($this->currentRegion);
            $createOrderDetails->createIfNotExists((int)$orderId, true, $this->currentRegion);
        } finally {
            if (empty($this->session->data['alsendo_pickup_point'])) {
                unset($this->session->data['current_order_id']);
            }
        }
    }

    public function ensureSyncedSelectedPointOnSuccess(string $route, array &$data): void
    {
        $this->registry->load->model('extension/alsendo/module/alsendo_order_details_shipping_address');

        $orderId = $this->session->data['current_order_id'] ?? null;
        $selectedPickupPointData = $this->session->data['alsendo_pickup_point'] ?? null;

        if (!$orderId) {
            return;
        }

        if (!$selectedPickupPointData) {
            $this->db->query("
                DELETE FROM `" . DB_PREFIX . "alsendo_order_pickup_points`
                WHERE order_id = '" . (int)$orderId . "'
            ");
            unset($this->session->data['alsendo_pickup_point']);
            unset($this->session->data['current_order_id']);
            $this->registry->model_extension_alsendo_module_alsendo_order_details_shipping_address->updatePickupPointByOrderId($orderId, null);

            return;
        }

        $pickupPointToSaveArray = json_decode(html_entity_decode($selectedPickupPointData), true);
        $pickupPointToSave = json_encode($pickupPointToSaveArray);

        $this->db->query("
            INSERT INTO `" . DB_PREFIX . "alsendo_order_pickup_points`
                SET order_id = '" . (int)$orderId . "',
                    pickup_point = '" . $this->db->escape($pickupPointToSave) . "'
            ON DUPLICATE KEY UPDATE pickup_point = VALUES(pickup_point)
        ");
        unset($this->session->data['alsendo_pickup_point']);
        unset($this->session->data['current_order_id']);

        $this->registry->model_extension_alsendo_module_alsendo_order_details_shipping_address->updatePickupPointByOrderId($orderId, $pickupPointToSaveArray);
    }

    public function getSessionData(): void
    {
        $sessionData = $this->session->data;

        $postCode = $sessionData['shipping_address']['postcode'] ?? null;
        $country = $sessionData['shipping_address']['country'] ?? null;

        $this->response->addHeader('Content-Type: application/json');
        $this->response->setOutput(json_encode([
            'post_code' => $postCode,
            'country' => $country,
        ]));
    }
}
