<?php

namespace Opencart\Admin\Model\Extension\Alsendo\Module;

require_once(DIR_EXTENSION . 'alsendo/src/DTO/Entity/OrderDetailsEntityFactoryInterface.php');
require_once(DIR_EXTENSION . 'alsendo/src/DTO/Entity/Apaczka/ApaczkaOrderDetailsEntityFactory.php');

use Opencart\Extension\Alsendo\DTO\Entity\AbstractOrderDetailsPackageDetailsEntity;
use Opencart\Extension\Alsendo\DTO\Entity\OrderDetailsEntityFactoryInterface;
use Opencart\Extension\Alsendo\DTO\Entity\Apaczka\ApaczkaOrderDetailsEntityFactory;
use Opencart\System\Engine\Model;
use Opencart\System\Engine\Registry;

class AlsendoOrderDetailsPackageDetails extends Model
{
    public function __construct(Registry $registry)
    {
        parent::__construct($registry);
    }

    public function populate(): void
    {
        $this->db->query("
            CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "alsendo_order_details_package_details` (
                `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
                `order_details_id` INT(11) UNSIGNED DEFAULT NULL,
                `template_id` INT(11) NULL DEFAULT NULL,
                `template_name` VARCHAR(255) NULL DEFAULT NULL,
                `cod_value` VARCHAR(255) NULL DEFAULT NULL,
                `declared_value` VARCHAR(255) NULL DEFAULT NULL,
                `package_content` VARCHAR(255) NULL DEFAULT NULL,
                `pickup_request` VARCHAR(255) NULL DEFAULT NULL,
                `pickup_request_date` VARCHAR(255) NULL DEFAULT NULL,
                `pickup_type` VARCHAR(255) NULL DEFAULT NULL,
                `ship_via_pickup_point` VARCHAR(255) NULL DEFAULT NULL,
                PRIMARY KEY (`id`),
                CONSTRAINT `fk_alsendo_order_details_package_details_order_details`
                    FOREIGN KEY (`order_details_id`)
                    REFERENCES `" . DB_PREFIX . "alsendo_order_details` (`id`)
                    ON DELETE CASCADE,
                CONSTRAINT `fk_alsendo_order_details_package_details_template`
                    FOREIGN KEY (`template_id`)
                    REFERENCES `" . DB_PREFIX . "alsendo_shipping_settings_templates` (`id`)
                    ON DELETE SET NULL
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
        ");
    }

    public function getPackageDetailsByOrderDetailsId(int $orderDetailsId, ?OrderDetailsEntityFactoryInterface $factory = null, string $currencyCode = 'PLN'): ?AbstractOrderDetailsPackageDetailsEntity
    {
        $query = $this->db->query("
            SELECT *
            FROM `" . DB_PREFIX . "alsendo_order_details_package_details`
            WHERE order_details_id = '" . (int)$orderDetailsId . "'
            LIMIT 1
        ");
        if (!$query->num_rows) {
            return null;
        }
        $factory = $factory ?? new ApaczkaOrderDetailsEntityFactory();
        return $factory->createPackageDetailsFromArray($query->row, $currencyCode);
    }

    public function insertPackageDetails(int $orderDetailsId, array $data): int
    {
        $this->db->query("
            INSERT INTO `" . DB_PREFIX . "alsendo_order_details_package_details`
            SET `order_details_id` = '" . (int)$orderDetailsId . "',
                `template_id` = " . (array_key_exists('template_id', $data) && $data['template_id'] !== null && $data['template_id'] !== '' ? "'" . (int)$data['template_id'] . "'" : "NULL") . ",
                `template_name` = " . (array_key_exists('template_name', $data) ? ($data['template_name'] === null ? "NULL" : "'" . $this->db->escape($data['template_name']) . "'") : "NULL") . ",
                `cod_value` = " . (array_key_exists('cod_value', $data) ? ($data['cod_value'] === null ? "NULL" : "'" . $this->db->escape((string)$data['cod_value']) . "'") : "NULL") . ",
                `declared_value` = " . (array_key_exists('declared_value', $data) ? ($data['declared_value'] === null ? "NULL" : "'" . $this->db->escape((string)$data['declared_value']) . "'") : "NULL") . ",
                `package_content` = " . (array_key_exists('package_content', $data) ? ($data['package_content'] === null ? "NULL" : "'" . $this->db->escape($data['package_content']) . "'") : "NULL") . ",
                `pickup_request` = " . (array_key_exists('pickup_request', $data) ? ($data['pickup_request'] === null ? "NULL" : "'" . $this->db->escape((string)$data['pickup_request']) . "'") : "NULL") . ",
                `pickup_request_date` = " . (array_key_exists('pickup_request_date', $data) ? ($data['pickup_request_date'] === null ? "NULL" : "'" . $this->db->escape((string)$data['pickup_request_date']) . "'") : "NULL") . ",
                `pickup_type` = " . (array_key_exists('pickup_type', $data) ? ($data['pickup_type'] === null ? "NULL" : "'" . $this->db->escape($data['pickup_type']) . "'") : "NULL") . ",
                `ship_via_pickup_point` = " . (array_key_exists('ship_via_pickup_point', $data) ? ($data['ship_via_pickup_point'] === null ? "NULL" : "'" . $this->db->escape((string)$data['ship_via_pickup_point']) . "'") : "NULL") . "
        ");
        return (int)$this->db->getLastId();
    }

    public function updatePackageDetails(int $packageDetailsId, array $data): void
    {
        $updates = [];

        if (array_key_exists('template_id', $data)) {
            $updates[] = ($data['template_id'] === null || $data['template_id'] === '') ? "`template_id` = NULL" : "`template_id` = '" . (int)$data['template_id'] . "'";
        }

        if (array_key_exists('template_name', $data)) {
            $updates[] = $data['template_name'] === null ? "`template_name` = NULL" : "`template_name` = '" . $this->db->escape($data['template_name']) . "'";
        }

        if (array_key_exists('cod_value', $data)) {
            $updates[] = $data['cod_value'] === null ? "`cod_value` = NULL" : "`cod_value` = '" . $this->db->escape((string)$data['cod_value']) . "'";
        }

        if (array_key_exists('declared_value', $data)) {
            $updates[] = $data['declared_value'] === null ? "`declared_value` = NULL" : "`declared_value` = '" . $this->db->escape((string)$data['declared_value']) . "'";
        }

        if (array_key_exists('package_content', $data)) {
            $updates[] = $data['package_content'] === null ? "`package_content` = NULL" : "`package_content` = '" . $this->db->escape($data['package_content']) . "'";
        }

        if (array_key_exists('pickup_request', $data)) {
            $updates[] = $data['pickup_request'] === null ? "`pickup_request` = NULL" : "`pickup_request` = '" . $this->db->escape((string)$data['pickup_request']) . "'";
        }

        if (array_key_exists('pickup_request_date', $data)) {
            $updates[] = $data['pickup_request_date'] === null ? "`pickup_request_date` = NULL" : "`pickup_request_date` = '" . $this->db->escape((string)$data['pickup_request_date']) . "'";
        }

        if (array_key_exists('pickup_type', $data)) {
            $updates[] = $data['pickup_type'] === null ? "`pickup_type` = NULL" : "`pickup_type` = '" . $this->db->escape($data['pickup_type']) . "'";
        }

        if (array_key_exists('ship_via_pickup_point', $data)) {
            $updates[] = $data['ship_via_pickup_point'] === null ? "`ship_via_pickup_point` = NULL" : "`ship_via_pickup_point` = '" . $this->db->escape((string)$data['ship_via_pickup_point']) . "'";
        }

        if (!empty($updates)) {
            $this->db->query("
                UPDATE `" . DB_PREFIX . "alsendo_order_details_package_details`
                SET " . implode(", ", $updates) . "
                WHERE `id` = '" . (int)$packageDetailsId . "'
            ");
        }
    }
}
