<?php
/**
 * NOTICE OF LICENSE.
 *
 * Copyright 2022 Kosmonaft.dev
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 *  @author    Alexandre DEBUSSCHÈRE <alexandre@kosmonaft.dev>
 *  @copyright 2022 - 2023 Kosmonaft.dev
 *  @license   MIT
 */

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

require_once _PS_MODULE_DIR_.'mrmax/vendor/autoload.php';

/**
 * Class MRMax
 */
class MRMax extends CarrierModule
{

    use MRMaxModuleTrait;

    /** @var int */
    public $id_carrier;

    /**
     * MRMax constructor
     */
    public function __construct()
    {
        $this->name = 'mrmax';
        $this->tab = 'shipping_logistics';
        $this->version = '1.4.6';
        $this->author = 'Kosmonaft.dev';
        $this->need_instance = 0;
        $this->module_key = '90005283df4877e2dc0d899301ca77b0';
        $this->bootstrap = true;

        parent::__construct();

        $this->displayName = $this->l('Mondial Relay Max');
        $this->description = $this->l('Fully integrated Mondial Relay solution for your shop.');
        $this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
    }

    /**
     * @return bool
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    public function install()
    {
        if (!extension_loaded('curl')) {
            $this->_errors[] = $this->l('cURL Extension has to be enabled.');
            return false;
        }

        if (!extension_loaded('soap')) {
            $this->_errors[] = $this->l('Soap Extension has to be enabled.');
            return false;
        }

        require_once dirname(__FILE__).'/sql/install.php';

        return parent::install() &&
            (new MRMaxHook(null, null, null, null, $this))->addMondialRelayHooks() &&
            (new MRMaxEmployee())->addMondialRelayEmployee() &&
            $this->registerTabs() &&
            Configuration::updateGlobalValue('MRMAX_TOKEN', Tools::passwdGen(32));
    }

    /**
     * @return bool
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    public function uninstall()
    {
        require_once dirname(__FILE__).'/sql/uninstall.php';

        (new MRMaxHook(null, null, null, null, $this))->removeMondialRelayHooks();
        (new MRMaxEmployee())->removeMondialRelayEmployee();
        (new MRMaxCarrier())->removeMondialRelayCarriers();

        $configurations = array_merge(
            ['MRMAX_TOKEN'],
            MRMaxForm::getConfigFormKeys()
        );

        foreach ($configurations as $configuration) {
            Configuration::deleteByName($configuration);
        }

        $this->unregisterTabs();

        return parent::uninstall();
    }

    /**
     * @return string
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     * @throws SmartyException
     */
    public function getContent()
    {
        $messages = '';

        if (!Configuration::get('PS_SHOP_ENABLE')) {
            $this->context->smarty->assign(
                'maintenance_page',
                Context::getContext()->link->getAdminLink('AdminMaintenance')
            );

            $messages .= $this->context->smarty->fetch($this->local_path.'views/templates/admin/maintenance_warning.tpl');
        }

        if (((bool)Tools::isSubmit('submitMrmaxModule')) == true) {
            $messages .= $this->postProcess();
        }

        $this->context->smarty->assign([
            'module_dir' => $this->_path,
            'checks_url' => $this->context->link->getModuleLink($this->name, 'checks', [
                'token' => Configuration::get('MRMAX_TOKEN')
            ]),
            'create_url' => $this->context->link->getModuleLink($this->name, 'createcarrier', [
                'token' => Configuration::get('MRMAX_TOKEN')
            ]),
        ]);

        $output = $this->context->smarty->fetch($this->local_path.'views/templates/admin/configure.tpl');

        return $messages.$output.(new MRMaxForm($this))->render();
    }

    /**
     * @return string
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function postProcess()
    {
        require_once dirname(__FILE__).'/sql/install.php';

        (new MRMaxHook(null, null, null, null, $this))->addMondialRelayHooks();
        (new MRMaxEmployee())->addMondialRelayEmployee();
        MRMaxUpgrade::migrate();

        $this->registerTabs();

        $success = true;
        foreach (MRMaxForm::getConfigFormKeys() as $key) {
            $success &= Configuration::updateValue($key, Tools::getValue($key));
        }

        if (!$success) {
            return $this->displayError($this->l(
                'Invalid Configuration value(s), unable to save the entire configuration...'
            ));
        }

        return $this->displayConfirmation($this->l('Settings updated !'));
    }

    /**
     * @param Cart $cart
     * @param float $shipping_cost
     * @return float|bool
     */
    public function getOrderShippingCost($cart, $shipping_cost)
    {
        if (!$this->active || $shipping_cost < 0) {
            return false;
        }

        $address = new Address((int)$cart->id_address_delivery);
        if (!isset($this->context->customer) || !Validate::isLoadedObject($this->context->customer) ||
            !Validate::isLoadedObject($address)) {
            return (float)$shipping_cost;
        }

        $iso = Tools::strtoupper(Country::getIsoById((int)$address->id_country));
        if (!in_array($iso, (new MRMaxCarrier())->getCountries())) {
            return false;
        }

        $carrier = new MRMaxCarrier($this->id_carrier);
        if (!Validate::isLoadedObject($carrier)) {
            return false;
        }

        if (!$carrier->canDeliverInCountry($iso)) {
            return false;
        }

        return (float)$shipping_cost;
    }

    /**
     * @param Cart $params
     * @return float|bool
     */
    public function getOrderShippingCostExternal($params)
    {
        return $this->getOrderShippingCost($params, 0);
    }
}
