<?php

namespace Opencart\Extension\Alsendo\Repositories;

require_once(DIR_EXTENSION . 'alsendo/src/Models/AdditionalSettings.php');

use Opencart\Extension\Alsendo\Models\AdditionalSettings;

class AdditionalSettingsRepository
{
    private object $db;
    private string $tablePrefix;
    private string $tableName;

    public function __construct(object $db, string $tablePrefix = '')
    {
        $this->db = $db;
        $this->tablePrefix = $tablePrefix ?: (defined('\DB_PREFIX') ? \DB_PREFIX : '');
        $this->tableName = $this->tablePrefix . 'alsendo_additional_settings';
    }

    public function getSettings(): ?AdditionalSettings
    {
        if (!$this->tableExists()) {
            return null;
        }
        
        $query = $this->db->query("SELECT * FROM `" . $this->tableName . "` LIMIT 1");
        
        if (!$query->num_rows) {
            return null;
        }
        
        return $this->createSettingsFromRow($query->row);
    }

    public function saveSettings(AdditionalSettings $settings): int
    {
        $existingSettings = $this->getSettings();

        if ($existingSettings) {
            $this->updateSettings($settings);
            return $existingSettings->getId();
        }

        $sql = "INSERT INTO `" . $this->tableName . "` SET 
            `inpost_default_point` = '" . $this->db->escape($this->encodePoint($settings->getInpostDefaultPoint())) . "',
            `dhl_default_point` = '" . $this->db->escape($this->encodePoint($settings->getDhlDefaultPoint())) . "',
            `orlen_default_point` = '" . $this->db->escape($this->encodePoint($settings->getOrlenDefaultPoint())) . "',
            `poczta_polska_default_point` = '" . $this->db->escape($this->encodePoint($settings->getPocztaPolskaDefaultPoint())) . "',
            `dpd_default_point` = '" . $this->db->escape($this->encodePoint($settings->getDpdDefaultPoint())) . "',
            `ups_default_point` = '" . $this->db->escape($this->encodePoint($settings->getUpsDefaultPoint())) . "',
            `balikovna_default_point` = '" . $this->db->escape($this->encodePoint($settings->getBalikovnaDefaultPoint())) . "',
            `gls_default_point` = '" . $this->db->escape($this->encodePoint($settings->getGlsDefaultPoint())) . "',
            `ppl_default_point` = '" . $this->db->escape($this->encodePoint($settings->getPplDefaultPoint())) . "',
            `zasilkovna_default_point` = '" . $this->db->escape($this->encodePoint($settings->getZasilkovnaDefaultPoint())) . "',
            `sameday_default_point` = '" . $this->db->escape($this->encodePoint($settings->getSamedayDefaultPoint())) . "',
            `fan_courier_default_point` = '" . $this->db->escape($this->encodePoint($settings->getFanCourierDefaultPoint())) . "',
            `cargus_default_point` = '" . $this->db->escape($this->encodePoint($settings->getCargusDefaultPoint())) . "',
            `pickup_hour_from` = '" . $this->db->escape($settings->getPickupHourFrom() ?: '') . "',
            `pickup_hour_to` = '" . $this->db->escape($settings->getPickupHourTo() ?: '') . "',
            `auto_declared_value` = '" . (int)$settings->getAutoDeclaredValue() . "',
            `sameday_dispatch` = '" . (int)$settings->getSamedayDispatch() . "'";

        $this->db->query($sql);
        return (int) $this->db->getLastId();
    }

    public function updateSettings(AdditionalSettings $settings): void
    {
        $sql = "UPDATE `" . $this->tableName . "` SET 
            `inpost_default_point` = '" . $this->db->escape($this->encodePoint($settings->getInpostDefaultPoint())) . "',
            `dhl_default_point` = '" . $this->db->escape($this->encodePoint($settings->getDhlDefaultPoint())) . "',
            `orlen_default_point` = '" . $this->db->escape($this->encodePoint($settings->getOrlenDefaultPoint())) . "',
            `poczta_polska_default_point` = '" . $this->db->escape($this->encodePoint($settings->getPocztaPolskaDefaultPoint())) . "',
            `dpd_default_point` = '" . $this->db->escape($this->encodePoint($settings->getDpdDefaultPoint())) . "',
            `ups_default_point` = '" . $this->db->escape($this->encodePoint($settings->getUpsDefaultPoint())) . "',
            `balikovna_default_point` = '" . $this->db->escape($this->encodePoint($settings->getBalikovnaDefaultPoint())) . "',
            `gls_default_point` = '" . $this->db->escape($this->encodePoint($settings->getGlsDefaultPoint())) . "',
            `ppl_default_point` = '" . $this->db->escape($this->encodePoint($settings->getPplDefaultPoint())) . "',
            `zasilkovna_default_point` = '" . $this->db->escape($this->encodePoint($settings->getZasilkovnaDefaultPoint())) . "',
            `sameday_default_point` = '" . $this->db->escape($this->encodePoint($settings->getSamedayDefaultPoint())) . "',
            `fan_courier_default_point` = '" . $this->db->escape($this->encodePoint($settings->getFanCourierDefaultPoint())) . "',
            `cargus_default_point` = '" . $this->db->escape($this->encodePoint($settings->getCargusDefaultPoint())) . "',
            `pickup_hour_from` = '" . $this->db->escape($settings->getPickupHourFrom() ?: '') . "',
            `pickup_hour_to` = '" . $this->db->escape($settings->getPickupHourTo() ?: '') . "',
            `auto_declared_value` = '" . (int)$settings->getAutoDeclaredValue() . "',
            `sameday_dispatch` = '" . (int)$settings->getSamedayDispatch() . "'";

        if ($settings->getId()) {
            $sql .= " WHERE `id` = '" . (int)$settings->getId() . "'";
        }

        $this->db->query($sql);
    }

    private function tableExists(): bool
    {
        try {
            $query = $this->db->query("SHOW TABLES LIKE '" . $this->tableName . "'");
            return $query->num_rows > 0;
        } catch (\Exception $e) {
            return false;
        }
    }

    private function createSettingsFromRow(array $row): AdditionalSettings
    {
        return new AdditionalSettings(
            (int)$row['id'],
            $this->decodePoint($row['inpost_default_point'] ?? null),
            $this->decodePoint($row['dhl_default_point'] ?? null),
            $this->decodePoint($row['orlen_default_point'] ?? null),
            $this->decodePoint($row['poczta_polska_default_point'] ?? null),
            $this->decodePoint($row['dpd_default_point'] ?? null),
            $this->decodePoint($row['ups_default_point'] ?? null),
            $this->decodePoint($row['balikovna_default_point'] ?? null),
            $this->decodePoint($row['gls_default_point'] ?? null),
            $this->decodePoint($row['ppl_default_point'] ?? null),
            $this->decodePoint($row['zasilkovna_default_point'] ?? null),
            $this->decodePoint($row['sameday_default_point'] ?? null),
            $this->decodePoint($row['fan_courier_default_point'] ?? null),
            $this->decodePoint($row['cargus_default_point'] ?? null),
            !empty($row['pickup_hour_from']) ? $row['pickup_hour_from'] : null,
            !empty($row['pickup_hour_to']) ? $row['pickup_hour_to'] : null,
            !empty($row['auto_declared_value']) ? (bool)$row['auto_declared_value'] : false,
            !empty($row['sameday_dispatch'] ?? null) ? (bool)$row['sameday_dispatch'] : false
        );
    }

    private function encodePoint(?array $point): string
    {
        return $point ? json_encode($point) : '';
    }

    private function decodePoint(?string $point): ?array
    {
        if (empty($point)) {
            return null;
        }
        
        $decoded = json_decode($point, true);
        return is_array($decoded) ? $decoded : null;
    }
} 