<?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;
}

/**
 * Class MRMaxForm
 */
class MRMaxForm
{

    const CARRIER_LIST = 1;
    const CARRIER_MAP = 2;

    /** @var MRMax */
    protected $module;

    /**
     * @param MRMax|null $module
     */
    public function __construct($module = null)
    {
        if ($module != null && !$module instanceof MRMax) {
            throw new InvalidArgumentException('Module is not an instance of MRMax.');
        }

        $this->module = $module ?: new MRMax();
    }

    /**
     * @param string $string
     * @return string
     */
    protected function l($string)
    {
        return $this->module->l($string, self::class);
    }

    /**
     * @return string
     * @throws PrestaShopException
     * @throws SmartyException
     */
    public function render()
    {
        $helper = new MRMaxHelperForm($this->module);

        $helper->tpl_vars = [
            'fields_value' => $this->getConfigFormValues(),
            'selected_tab' => Tools::getValue($helper->submit_action, 'credentials')
        ];

        return $helper->generateForm($this->getConfigForm());
    }

    /**
     * @return string[]
     */
    public static function getConfigFormKeys()
    {
        return [
            'MRMAX_TRADING_NAME',
            'MRMAX_BRAND_CODE',
            'MRMAX_WS_KEY',
            'MRMAX_CARRIERS_MAP',
            'MRMAX_ADDRESS_COMPANY',
            'MRMAX_ADDRESS_ADDR1',
            'MRMAX_ADDRESS_ADDR2',
            'MRMAX_ADDRESS_ADDR3',
            'MRMAX_ADDRESS_ZIP',
            'MRMAX_ADDRESS_CITY',
            'MRMAX_ADDRESS_COUNTRY',
            'MRMAX_ADDRESS_PHONE',
            'MRMAX_ADDRESS_EMAIL',
            'MRMAX_ADDRESS_HSCODE',
            'MRMAX_ADDRESS_EORI',
            'MRMAX_ADDRESS_ORIGIN',
            'MRMAX_ADDRESS_FORMAT',
            'MRMAX_ORDER_STATE',
            'MRMAX_LABEL_FORMAT',
            'MRMAX_REGISTERED_PACKAGE_STATE',
            'MRMAX_INCHARGE_PACKAGE_STATE',
            'MRMAX_DELIVERED_PACKAGE_STATE',
            'MRMAX_ANOMALY_PACKAGE_STATE',
            'MRMAX_TRACKING_CRON',
            'MRMAX_UNSELECTED_CARRIERS',
        ];
    }

    /**
     * @return array
     * @throws PrestaShopException
     */
    protected function getConfigFormValues()
    {
        $values = Configuration::getMultiple(self::getConfigFormKeys());
        $values['MRMAX_TRACKING_CRON'] = Context::getContext()->link->getModuleLink(
            $this->module->name,
            'tracking',
            [
                'token' => Configuration::get('MRMAX_TOKEN')
            ]
        );

        if (version_compare(_PS_VERSION_, '1.7', '<')) {
            $values['MRMAX_CARRIERS_MAP'] = MRMaxForm::CARRIER_MAP;
        }

        return $values;
    }

    /**
     * @return array[]
     * @throws SmartyException
     */
    protected function getConfigForm()
    {
        return [
            'credentials' => $this->getCredentialsForm(),
            'carriers' => $this->getCarriersForm(),
            'labeling' => $this->getLabelingForm(),
            'tracking' => $this->getTrackingForm()
        ];
    }

    /**
     * @return array[]
     * @throws SmartyException
     */
    protected function getCredentialsForm()
    {
        return [
            'form' => [
                'legend' => [
                    'title' => $this->l('Credentials'),
                    'icon' => 'icon-key',
                ],
                'input' => [
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'text',
                        'label' => $this->l('Trading name'),
                        'name' => 'MRMAX_TRADING_NAME',
                    ],
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'text',
                        'label' => $this->l('Brand code'),
                        'name' => 'MRMAX_BRAND_CODE',
                    ],
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'password',
                        'label' => $this->l('Web Service Key'),
                        'name' => 'MRMAX_WS_KEY',
                    ],
                    $this->getCta([
                        'type' => 'button',
                        'class' => 'btn-default',
                        'id' => 'checkCredentialsLogin',
                        'value' => $this->l('Check'),
                        'rel' => 'credentials_check'
                    ])
                ],
                'submit' => [
                    'title' => $this->l('Save'),
                ],
            ],
        ];
    }

    /**
     * @return array[]
     * @throws SmartyException
     */
    protected function getCarriersForm()
    {
        $mr_carrier = new MRMaxCarrier();
        $delivery_modes = $mr_carrier->getDeliveryModes();
        $insurances = $mr_carrier->getInsurances();

        return [
            'form' => [
                'legend' => [
                    'title' => $this->l('Carriers'),
                    'icon' => 'icon-truck',
                ],
                'input' => [
                    [
                        'type' => 'radio',
                        'label' => $this->l('Pickup display'),
                        'desc' => $this->l('Display only a list or a widget with an interactive map.'),
                        'name' => 'MRMAX_CARRIERS_MAP',
                        'class' => 't',
                        'is_bool' => true,
                        'values' => [
                            [
                                'id'    => 'carrier_map_off',
                                'value' => 1,
                                'label' => $this->l('Only a list')
                            ],
                            [
                                'id'    => 'carrier_map_on',
                                'value' => 2,
                                'label' => $this->l('Widget with interactive map')
                            ]
                        ],
                    ],
                    [
                        'type' => 'switch',
                        'label' => $this->l('Unselected carriers'),
                        'desc' => $this->l('Unselect all carriers when customers arrive on the carrier page.'),
                        'name' => 'MRMAX_UNSELECTED_CARRIERS',
                        'is_bool' => true,
                        'values' => [
                            [
                                'id'    => 'unselected_carrier_off',
                                'value' => false,
                                'label' => $this->l('No')
                            ],
                            [
                                'id'    => 'unselected_carrier_on',
                                'value' => true,
                                'label' => $this->l('Oui')
                            ]
                        ],
                    ],
                    $this->getDivider(),
                    [
                        'type' => 'html',
                        'label' => $this->l('Carriers list'),
                        'name' => '',
                        'html_content' => $this->fetchHtml('carriers_list.tpl', [
                            'carriers' => $mr_carrier->getMondialRelayCarriers(),
                            'carrier_ul' => Context::getContext()->link->getAdminLink(
                                'AdminCarrierWizard',
                                true
                            )
                        ])
                    ],
                    [
                        'type' => 'html',
                        'label' => $this->l('Create a new Mondial Relay carrier'),
                        'name' => '',
                        'html_content' => $this->fetchHtml('hr.tpl')
                    ],
                    [
                        'type' => 'html',
                        'label' => $this->l('Carrier Name'),
                        'name' => '',
                        'html_content' => $this->fetchHtml('input.tpl', [
                            'type' => 'text',
                            'id' => 'new_carrier_name',
                            'value' => ''
                        ])
                    ],
                    [
                        'type' => 'html',
                        'label' => $this->l('Delay'),
                        'name' => '',
                        'html_content' => $this->fetchHtml('input.tpl', [
                            'type' => 'text',
                            'id' => 'new_carrier_delay',
                            'value' => '',
                        ])
                    ],
                    [
                        'type' => 'html',
                        'label' => $this->l('Delivery mode'),
                        'name' => '',
                        'html_content' => $this->fetchHtml('select.tpl', [
                            'id' => 'new_carrier_mode',
                            'options' => [
                                'query' => array_map(function ($name, $mode) {
                                    return [
                                        'mode' => $mode,
                                        'name' => sprintf('%s - %s', $mode, $name)
                                    ];
                                }, $delivery_modes, array_keys($delivery_modes)),
                                'id' => 'mode',
                                'name' => 'name'
                            ]
                        ])
                    ],
                    [
                        'type' => 'html',
                        'label' => $this->l('Insurance'),
                        'name' => '',
                        'html_content' => $this->fetchHtml('select.tpl', [
                            'id' => 'new_carrier_insurance',
                            'options' => [
                                'query' => array_map(function ($name, $insurance) {
                                    return [
                                        'insurance' => $insurance,
                                        'name' => $name
                                    ];
                                }, $insurances, array_keys($insurances)),
                                'id' => 'insurance',
                                'name' => 'name'
                            ]
                        ])
                    ],
                    $this->getCta([
                        'type' => 'button',
                        'class' => 'btn-primary fixed-width-xxl',
                        'id' => 'createNewCarrier',
                        'value' => $this->l('Create the new carrier')
                    ])
                ],
                'submit' => [
                    'title' => $this->l('Save'),
                ],
            ]
        ];
    }

    /**
     * @return array[]
     * @throws SmartyException
     */
    protected function getLabelingForm()
    {
        return [
            'form' => [
                'legend' => [
                    'title' => $this->l('Labeling'),
                    'icon' => 'icon-file',
                ],
                'input' => [
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'text',
                        'label' => $this->l('Company'),
                        'name' => 'MRMAX_ADDRESS_COMPANY',
                        'required' => true
                    ],
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'text',
                        'label' => $this->l('Address 1'),
                        'name' => 'MRMAX_ADDRESS_ADDR1',
                        'required' => true
                    ],
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'text',
                        'label' => $this->l('Address 2'),
                        'name' => 'MRMAX_ADDRESS_ADDR2',
                    ],
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'text',
                        'label' => $this->l('Address 3'),
                        'name' => 'MRMAX_ADDRESS_ADDR3',
                    ],
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'text',
                        'label' => $this->l('Postcode'),
                        'name' => 'MRMAX_ADDRESS_ZIP',
                        'required' => true
                    ],
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'text',
                        'label' => $this->l('City'),
                        'name' => 'MRMAX_ADDRESS_CITY',
                        'required' => true
                    ],
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'select',
                        'label' => $this->l('Country'),
                        'name' => 'MRMAX_ADDRESS_COUNTRY',
                        'options' => [
                            'query' => Country::getCountries(Context::getContext()->language->id, true),
                            'id' => 'id_country',
                            'name' => 'name'
                        ],
                        'required' => true
                    ],
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'text',
                        'label' => $this->l('Phone'),
                        'name' => 'MRMAX_ADDRESS_PHONE',
                        'required' => true
                    ],
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'text',
                        'label' => $this->l('Email'),
                        'name' => 'MRMAX_ADDRESS_EMAIL',
                        'required' => true
                    ],
                    $this->getDivider(),
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'select',
                        'label' => $this->l('Order state after label creation'),
                        'name' => 'MRMAX_ORDER_STATE',
                        'options' => [
                            'query' => OrderState::getOrderStates(Context::getContext()->language->id),
                            'id' => 'id_order_state',
                            'name' => 'name'
                        ]
                    ],
                    $this->getDivider(),
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'select',
                        'label' => $this->l('Labels format'),
                        'name' => 'MRMAX_LABEL_FORMAT',
                        'options' => [
                            'query' => [
                                [
                                    'id' => 'A4',
                                    'name' => 'A4'
                                ],
                                [
                                    'id' => 'A5',
                                    'name' => 'A5'
                                ],
                                [
                                    'id' => '10x15',
                                    'name' => '10x15'
                                ]
                            ],
                            'id' => 'id',
                            'name' => 'name'
                        ]
                    ]
                ],
                'submit' => [
                    'title' => $this->l('Save'),
                ],
            ],
        ];
    }

    /**
     * @return array[]
     * @throws SmartyException
     */
    protected function getTrackingForm()
    {
        $order_states = array_merge(
            [[
                'id_order_state' => 0,
                'name' => $this->l('Do not change the order status')
            ]],
            OrderState::getOrderStates(Context::getContext()->language->id)
        );

        return [
            'form' => [
                'legend' => [
                    'title' => $this->l('Tracking'),
                    'icon' => 'icon-envelope',
                ],
                'input' => [
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'select',
                        'label' => $this->l('Registered Package'),
                        'desc' => $this->l('Your package information has been sent to Mondial Relay.'),
                        'name' => 'MRMAX_REGISTERED_PACKAGE_STATE',
                        'options' => [
                            'query' => $order_states,
                            'id' => 'id_order_state',
                            'name' => 'name'
                        ]
                    ],
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'select',
                        'label' => $this->l('Package taken in charge'),
                        'desc' => $this->l('Your package is being handled by Mondial Relay.'),
                        'name' => 'MRMAX_INCHARGE_PACKAGE_STATE',
                        'options' => [
                            'query' => $order_states,
                            'id' => 'id_order_state',
                            'name' => 'name'
                        ]
                    ],
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'select',
                        'label' => $this->l('Package delivered'),
                        'desc' => $this->l('Your package has been delivered by Mondial Relay.'),
                        'name' => 'MRMAX_DELIVERED_PACKAGE_STATE',
                        'options' => [
                            'query' => $order_states,
                            'id' => 'id_order_state',
                            'name' => 'name'
                        ]
                    ],
                    [
                        'class' => 'fixed-width-xxl',
                        'type' => 'select',
                        'label' => $this->l('Anomaly'),
                        'desc' => $this->l('Mondial Relay signals an anomaly with your package.'),
                        'name' => 'MRMAX_ANOMALY_PACKAGE_STATE',
                        'options' => [
                            'query' => $order_states,
                            'id' => 'id_order_state',
                            'name' => 'name'
                        ]
                    ],
                    $this->getDivider(),
                    [
                        'class' => 'col-lg-12',
                        'type' => 'text',
                        'label' => $this->l('Cron task'),
                        'name' => 'MRMAX_TRACKING_CRON',
                        'disabled' => true
                    ]
                ],
                'submit' => [
                    'title' => $this->l('Save'),
                ],
            ]
        ];
    }

    /**
     * @return array
     * @throws SmartyException
     */
    private function getDivider()
    {
        return [
            'type' => 'html',
            'label' => '',
            'name' => '',
            'html_content' => $this->fetchHtml('hr.tpl')
        ];
    }

    /**
     * @param array $smarty_vars
     * @return array
     * @throws SmartyException
     */
    private function getCta($smarty_vars)
    {
        return [
            'type' => 'html',
            'label' => '',
            'name' => '',
            'html_content' => $this->fetchHtml('cta.tpl', $smarty_vars)
        ];
    }

    /**
     * @return false|string
     * @throws SmartyException
     */
    private function fetchHtml($file, $smarty_vars = [])
    {
        Context::getContext()->smarty->assign($smarty_vars);

        return Context::getContext()->smarty->fetch(
            $this->module->getLocalPath().'views/templates/admin/'.$file
        );
    }
}
