<?php

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

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

use Opencart\Extension\Alsendo\DTO\Entity\AlsendoRegionEntity;
use Opencart\System\Engine\Model;
use Opencart\System\Engine\Registry;

class AlsendoRegion extends Model {

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

    public function populate(): void {
        $this->load->model('localisation/country');
        $this->load->model('localisation/currency');

        $countries = [
            'PL' => ['name' => 'Poland', 'iso_code_2' => 'PL', 'iso_code_3' => 'POL', 'address_format_id' => '1', 'postcode_required' => '1', 'status' => '1'],
            'RO' => ['name' => 'Romania', 'iso_code_2' => 'RO', 'iso_code_3' => 'ROM', 'address_format_id' => '1', 'postcode_required' => '1', 'status' => '1'],
            'CZ' => ['name' => 'Czechia', 'iso_code_2' => 'CZ', 'iso_code_3' => 'CZE', 'address_format_id' => '1', 'postcode_required' => '1', 'status' => '1'],
        ];

        $countriesIso3 = [
            'PL' => 'POL',
            'RO' => 'ROM',
            'CZ' => 'CZE'
        ];

        $countryDescriptions = [
            'PL' => [
                170 => [
                    'name' => 'Poland'
                ]
            ],
            'CZ' => [
                56 => [
                    'name' => 'Czech Republic'
                ]
            ],
            'RO' => [
                175 => [
                    'name' => 'Romania'
                ]
            ]
        ];

        $countryIds = [];

        foreach ($countries as $iso2 => $data) {
            $country = $this->model_localisation_country->getCountryByIsoCode2($iso2);

            $oc4 = false;
            if (!$country) {
                $country = $this->model_localisation_country->getCountryByIsoCode2($countriesIso3[$iso2]);
                $oc4 = true;
            }

            if (!$country) {

                if ($oc4 === true) {
                    $data['country_description'] = $countryDescriptions[$iso2];
                }

                $countryIds[$iso2] = $this->model_localisation_country->addCountry($data);
            } else {
                $countryIds[$iso2] = $country['country_id'];
            }
        }

        $usdCurrency = $this->model_localisation_currency->getCurrencyByCode('USD');
        $usdCurrencyValue = $usdCurrency['value'];

        $currencyValues = [
            'PLN' => $usdCurrencyValue * 3.65,
            'CZK' => $usdCurrencyValue * 20.89,
            'RON' => $usdCurrencyValue * 4.33,
        ];

        $currencies = [
            'PLN' => [
                'code' => 'PLN', 'title' => 'Polish Zloty', 'symbol_left' => '', 'symbol_right' => 'zł',
                'decimal_place' => '2', 'value' => $currencyValues['PLN'], 'status' => true
            ],
            'RON' => [
                'code' => 'RON', 'title' => 'Romanian Leu', 'symbol_left' => '', 'symbol_right' => 'lei',
                'decimal_place' => '2', 'value' => $currencyValues['RON'], 'status' => true
            ],
            'CZK' => [
                'code' => 'CZK', 'title' => 'Czech Koruna', 'symbol_left' => '', 'symbol_right' => 'Kč',
                'decimal_place' => '2', 'value' => $currencyValues['CZK'], 'status' => true
            ],
        ];

        $currencyIds = [];

        foreach ($currencies as $code => $data) {
            $currency = $this->model_localisation_currency->getCurrencyByCode($code);
            if (!$currency) {
                $currencyIds[$code] = $this->model_localisation_currency->addCurrency($data);
            } else {
                $currencyIds[$code] = $currency['currency_id'];
            }
        }

        $regions = [
            [
                'name' => 'Poland',
                'code' => 'poland',
                'country_id' => $countryIds['PL'],
                'currency_id' => $currencyIds['PLN'],
                'active' => 1
            ],
            [
                'name' => 'Romania',
                'code' => 'romania',
                'country_id' => $countryIds['RO'],
                'currency_id' => $currencyIds['RON'],
                'active' => 0
            ],
            [
                'name' => 'Czechia',
                'code' => 'czechia',
                'country_id' => $countryIds['CZ'],
                'currency_id' => $currencyIds['CZK'],
                'active' => 0
            ],
        ];

        foreach ($regions as $region) {
            $exists = $this->db->query("SELECT `id` FROM `" . DB_PREFIX . "alsendo_region` WHERE `name` = '" . $this->db->escape($region['name']) . "' LIMIT 1");
            if (!$exists->num_rows) {
                $this->db->query("INSERT INTO `" . DB_PREFIX . "alsendo_region` SET 
                `name` = '" . $this->db->escape($region['name']) . "', 
                `code` = '" . $this->db->escape($region['code']) . "',
                `country_id` = '" . $region['country_id'] . "',
                `currency_id` = '" . $region['currency_id'] . "',
                `active` = '" . (int)$region['active'] . "'");
            }
        }
    }

    public function getCurrentRegion(): ?AlsendoRegionEntity {
        $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "alsendo_region` WHERE `active` = 1 LIMIT 1");

        if ($query->num_rows) {
            return AlsendoRegionEntity::fromArray([
                'id' => (int)$query->row['id'],
                'name' => $query->row['name'],
                'code' => $query->row['code'],
                'active' => (bool)$query->row['active'],
                'country_id' => (int)$query->row['country_id'],
                'currency_id' => (int)$query->row['currency_id'],
            ]);
        }

        return null;
    }

    public function getRegionById(int $id): ?AlsendoRegionEntity {
        $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "alsendo_region` WHERE `id` = '" . (int)$id . "' LIMIT 1");

        if ($query->num_rows) {
            return AlsendoRegionEntity::fromArray([
                'id' => (int)$query->row['id'],
                'name' => $query->row['name'],
                'code' => $query->row['code'],
                'active' => (bool)$query->row['active'],
                'country_id' => (int)$query->row['country_id'],
                'currency_id' => (int)$query->row['currency_id'],
            ]);
        }

        return null;
    }

    public function getRegionByCode(string $code): ?AlsendoRegionEntity {
        $query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "alsendo_region` WHERE `code` = '" . $this->db->escape($code) . "' LIMIT 1");

        if ($query->num_rows) {
            return AlsendoRegionEntity::fromArray([
                'id' => (int)$query->row['id'],
                'name' => $query->row['name'],
                'code' => $query->row['code'],
                'active' => (bool)$query->row['active'],
                'country_id' => (int)$query->row['country_id'],
                'currency_id' => (int)$query->row['currency_id'],
            ]);
        }

        return null;
    }

    public function setRegionByCode(string $code): void {
        $query = $this->db->query("SELECT `id` FROM `".DB_PREFIX."alsendo_region` WHERE `code` = '".$this->db->escape($code)."' LIMIT 1");
        if ($query->num_rows) {
            $this->db->query("UPDATE `" . DB_PREFIX . "alsendo_region` SET `active` = 0");
            $this->db->query("UPDATE `" . DB_PREFIX . "alsendo_region` SET `active` = 1 WHERE `id` = '" . (int)$query->row['id'] . "'");
        }
    }

    public function setRegionById(int $id): void {
        $query = $this->db->query("SELECT `id` FROM `" . DB_PREFIX . "alsendo_region` WHERE `id` = '" . $id . "' LIMIT 1");
        if ($query->num_rows) {
            $this->db->query("UPDATE `" . DB_PREFIX . "alsendo_region` SET `active` = 0");
            $this->db->query("UPDATE `" . DB_PREFIX . "alsendo_region` SET `active` = 1 WHERE `id` = '" . $id . "'");
        }
    }

    public function upsertEntity(AlsendoRegionEntity $entity): void {
        $exists = $this->db->query("SELECT `id` FROM `" . DB_PREFIX . "alsendo_region` WHERE `id` = '" . $entity->id . "' LIMIT 1");
        if ($exists->num_rows) {
            $this->db->query("UPDATE `" . DB_PREFIX . "alsendo_region`
                SET `name` = '" . $this->db->escape($entity->name) . "',
                    `code` = '" . $this->db->escape($entity->code) . "',
                    `active` = '" . (int)$entity->isActive . "',
                    `currency_id` = '" . (int)$entity->currencyId . "',
                    `country_id` = '" . (int)$entity->countryId . "'
                WHERE `id` = '" . (int)$entity->id . "'");
        } else {
            $this->db->query("INSERT INTO `" . DB_PREFIX . "alsendo_region`
                SET `id` = '" . (int)$entity->id . "',
                    `name` = '" . $this->db->escape($entity->name) . "',
                    `code` = '" . $this->db->escape($entity->code) . "',
                    `currency_id` = '" . $entity->currencyId . "',
                    `country_id` = '" . $entity->countryId . "'
                    `active` = '" . (int)$entity->isActive . "'");
        }
    }
}