<?php
/**
 * 2007-2023 PrestaShop
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@prestashop.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
 * versions in the future. If you wish to customize PrestaShop for your
 * needs please refer to http://www.prestashop.com for more information.
 *
 *  @author    PrestaShop SA <contact@prestashop.com>
 *  @copyright 2007-2023 PrestaShop SA
 *  @license   http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 *  International Registered Trademark & Property of PrestaShop SA
 */
if (!defined('_PS_VERSION_')) {
    exit;
}

use Doctrine\ORM\EntityRepository;
use PrestaShop\Module\AgileMultisellerPro\Controller\Front\AgileModuleFrontController;
use PrestaShop\Module\AgileMultisellerPro\Controller\Front\Traits\SellerTrait;
use PrestaShop\Module\AgileMultisellerPro\Entity\Sellerinfo;
use PrestaShop\Module\AgileMultisellerPro\Entity\SellerinfoLang;
use PrestaShop\Module\AgileMultisellerPro\Helper\Form\SellerInfoForm;
use PrestaShopBundle\Entity\Lang;

include_once _PS_ROOT_DIR_ . '/src/PrestaShopBundle/Translation/Constraints/PassVsprintf.php';

class AgileMultiSellerProSellerSignupModuleFrontController extends AgileModuleFrontController
{
    use SellerTrait;

    public $auth = false;

    public function setMedia()
    {
        parent::setMedia();

        $deflang = new Language($this->context->language->id);
        $isoTinyMCE = (file_exists(_PS_ROOT_DIR_ . '/js/tiny_mce/langs/' . $deflang->iso_code .
            '.js') ? $deflang->iso_code : 'en');

        Media::addJsDef([
            'is_multilang_address' => true,
            'has_address' => true,
            'pathCSS' => _THEME_CSS_DIR_,
            'idSelectedCountry' => $this->getSelectedCountry(),
            'idSelectedState' => $this->getSelectedState(),
            'iso' => $isoTinyMCE,
            'ad' => str_replace('\\', '\\\\', dirname($_SERVER['PHP_SELF'])),
            'id_language_current' => $this->context->language->id,
            'agileCountries' => $this->getCountries(),
        ]);

        Media::addJsDefL('sellerbusiness_fileDefaultHtml', $this->context->getTranslator()->trans('No file selected', [], 'Modules.Agilemultisellerpro.Signup'));
        Media::addJsDefL('sellerbusiness_fileButtonHtml', $this->context->getTranslator()->trans('Choose file', [], 'Modules.Agilemultisellerpro.Signup'));

        $this->registerJavascript(
            'agile_statememneger',
            '/modules/agilemultisellerpro/views/js/AgileStatesManagement.js',
            ['position' => 'bottom', 'priority' => 100]
        );
        $this->registerJavascript(
            'agile_multilanguage',
            '/modules/agilemultisellerpro/views/js/multi-language.js',
            ['position' => 'bottom', 'priority' => 100]
        );
    }

    public function init()
    {
        parent::init();

        if ((int) Configuration::get('AGILE_MS_CUSTOMER_SELLER') != 1) {
            Tools::redirect(__PS_BASE_URI__);
        }

        if ($this->context->customer->isLogged()) {
            Tools::redirect($this->context->link->getModuleLink('agilemultisellerpro', 'sellersummary', [], true));
        }

        $languages = Language::getLanguages(false);

        $this->sellerinfo
            ->setPostcode(Tools::getValue('postcode', ''))
            ->setIdCountry((int) Tools::getValue('id_country', 0))
            ->setIdState((int) Tools::getValue('id_state', 0))
            ->setPhone(Tools::getValue('phone', ''));

        /** @var EntityRepository $sellerInfoRepository */
        $langRepository = $this->entityManager->getRepository(Lang::class);

        foreach ($languages as $lang) {
            $id_lang = $lang['id_lang'];
            $sil = new SellerinfoLang();
            $sil->setIdLang($langRepository->find((int) $id_lang));
            $sil->setCompany(Tools::getValue('company', ''));
            $sil->setAddress1(Tools::getValue('address1', ''));
            $sil->setAddress2(Tools::getValue('address2', ''));
            $sil->setCity(Tools::getValue('city', ''));
            $sil->setDescription(Tools::getValue('description', ''));
            $this->sellerinfo->addSellerLang($sil);
        }

        $this->context->smarty->assign([
            'languages' => $languages,
            'id_language_current' => $this->context->cookie->id_lang,
            'formFields' => (new SellerInfoForm($this->sellerinfo, $this->entityManager))->makeForm(true),
        ]);
    }

    public function initContent()
    {
        parent::initContent();

        $this->assignCountries();
        $this->assignVatNumber();
        $this->assignAddressFormat();

        $this->setTemplate('module:agilemultisellerpro/views/templates/front/sellersignup.tpl');
    }

    public function postProcess()
    {
        if (Tools::isSubmit('submitSellerinfo')) {
            $this->processSubmitSellerinfo();
        }
    }

    protected function processSubmitSellerinfo()
    {
        AgileMultiSellerPro::ensureDateCustomField();
        // $this->sellerinfo->date_add = date('Y-m-d H:i:s');

        $firstname = trim(Tools::getValue('firstname'));
        $lastname = trim(Tools::getValue('lastname'));
        $passwd = trim(Tools::getValue('passwd'));
        $email = trim(Tools::getValue('email'));

        if (empty($firstname) || !Validate::isName($firstname)) {
            $this->errors[] = $this->context->getTranslator()->trans('First name is invalid.', [], 'Modules.Agilemultisellerpro.Signup');
        }

        if (empty($lastname) || !Validate::isName($lastname)) {
            $this->errors[] = $this->context->getTranslator()->trans('Last name is invalid.', [], 'Modules.Agilemultisellerpro.Signup');
        }

        if (empty($email)) {
            $this->errors[] = $this->context->getTranslator()->trans('An email address required.', [], 'Modules.Agilemultisellerpro.Signup');
        } elseif (!Validate::isEmail($email)) {
            $this->errors[] = $this->context->getTranslator()->trans('Invalid email address.', [], 'Modules.Agilemultisellerpro.Signup');
        } elseif (empty($passwd)) {
            $this->errors[] = $this->context->getTranslator()->trans('Password is required.', [], 'Modules.Agilemultisellerpro.Signup');
        } elseif (!Validate::isAcceptablePasswordLength($passwd) || !Validate::isAcceptablePasswordScore($passwd)) {
            $this->errors[] = $this->context->getTranslator()->trans('Invalid password.', [], 'Modules.Agilemultisellerpro.Signup');
        }

        if (!empty($this->errors)) {
            return;
        }

        if (Customer::customerExists($email)) {
            $this->errors[] = $this->context->getTranslator()->trans(
                'An account using this email address has already been registered.',
                [],
                'Modules.Agilemultisellerpro.Signup'
            );
        }

        $this->sellerinfo->setIdCountry((int) Tools::getValue('id_country'));

        $data = Tools::getAllValues();

        foreach (Language::getLanguages(false) as $lang) {
            $idLang = $lang['id_lang'];
            $data['company_' . $idLang] = Tools::getValue('company', '');
            $data['address1_' . $idLang] = Tools::getValue('address1', '');
            $data['address2_' . $idLang] = Tools::getValue('address2', '');
            $data['city_' . $idLang] = Tools::getValue('city', '');
            $data['description_' . $idLang] = Tools::getValue('description', '');
        }

        $sellerInfoRepository = $this->entityManager->getRepository(Sellerinfo::class);
        $this->errors = array_merge($this->errors, $sellerInfoRepository->validateBySellerInfo($this->sellerinfo, $data));

        if (!($country = new Country($this->sellerinfo->getIdCountry())) || !Validate::isLoadedObject($country)) {
            throw new PrestaShopException('Country cannot be loaded with id_country');
        }

        if ((int) $country->contains_states) {
            $this->sellerinfo->setIdState((int) Tools::getValue('id_state'));
        }

        if ((int) $country->contains_states && !(int) $this->sellerinfo->getIdState()) {
            $this->errors[] = $this->context->getTranslator()->trans('This country requires a state selection.', [], 'Modules.Agilemultisellerpro.Signup');
        }

        if (!empty($this->errors)) {
            return;
        }

        $customer = new Customer();
        $customer->firstname = $firstname;
        $customer->lastname = $lastname;
        $customer->email = $email;
        $customer->is_guest = 0;
        $customer->newsletter = 0;
        $customer->optin = 0;
        $customer->active = 1;
        $customer->passwd = Tools::hash($passwd);

        if ($customer->add()) {
            if (!$this->sendConfirmationMail($customer)) {
                $this->context->getTranslator()->trans('The email cannot be sent.', [], 'Modules.Agilemultisellerpro.Signup');
            }
        } else {
            $this->context->getTranslator()->trans('Error during create a new customer account.', [], 'Modules.Agilemultisellerpro.Signup');

            return;
        }

        $id_lang = (int) Configuration::get('PS_LANG_DEFAULT');
        $address = new Address();
        $address->lastname = $customer->lastname;
        $address->firstname = $customer->firstname;
        $address->id_country = (int) Tools::getValue('id_country');
        $address->id_state = (int) Tools::getValue('id_state');
        $address->postcode = Tools::getValue('postcode');
        $address->phone = Tools::getValue('phone');
        $address->company = $data['company_' . $idLang];
        $address->city = $data['city_' . $idLang];
        $address->address1 = $data['address1_' . $idLang];
        $address->address2 = $data['address2_' . $idLang];
        $address->id_customer = $customer->id;
        $address->alias = 'My Home';
        $address->add();

        $this->updateContext($customer);
        Hook::exec('actionCustomerAccountAdd', [
            '_POST' => $_POST,
            'newCustomer' => $customer,
        ]);

        if (empty($this->_errors)) {
            $this->module->createSellerAccount($customer, $this->sellerinfo);

            $url = $this->context->link->getModuleLink('agilemultisellerpro', 'sellersummary', [], true);
            Tools::redirect($url);
        }
    }

    protected function sendConfirmationMail(Customer $customer)
    {
        if (!Configuration::get('PS_CUSTOMER_CREATION_EMAIL')) {
            return true;
        }

        return Mail::Send(
            $this->context->language->id,
            'account',
            Mail::l('Welcome!'),
            [
                '{firstname}' => $customer->firstname,
                '{lastname}' => $customer->lastname,
                '{email}' => $customer->email,
                '{passwd}' => Tools::getValue('passwd'), ],
            $customer->email,
            $customer->firstname . ' ' . $customer->lastname
        );
    }

    protected function updateContext(Customer $customer)
    {
        $this->context->updateCustomer($customer);
    }
}
