<?php

class actionUsersProfileEditPassword extends cmsAction {

    public $lock_explicit_call = true;
    protected $extended_langs = ['auth'];
    private $verify_exp = 24;

    public function run($profile) {

        // Владельцы и админы могут редактировать
        if (!$this->is_own_profile && !$this->cms_user->is_admin) {
            return cmsCore::error404();
        }

        // Администраторы тут могут редактировать только свои профили
        if ($this->cms_user->is_admin && !$this->is_own_profile && $profile['is_admin']) {
            return cmsCore::error404();
        }

        $form = $this->getForm('password', [$profile]);

        $ups_key = 'users.change_email_' . md5($profile['email']);

        // Если разрешено, добавляем возможность смены email
        if (cmsUser::isAllowed('users', 'change_email', true, true)) {

            // срок подтверждения истёк
            $verify_hours_exp = null;

            $show_email_field = true;

            $sended = cmsUser::getUPS($ups_key);

            // уже ранее меняли или мы в процессе
            if ($sended) {

                $diff_days = intval((time() - $sended['timestamp']) / 86400);

                $verify_hours_exp = round((time() - $sended['timestamp']) / 3600) >= $this->verify_exp;

                if (cmsUser::isPermittedLimitHigher('users', 'change_email_period', $diff_days, true)) {
                    $show_email_field = false;
                }
            }

            $form->addFieldsetAfter('basic', LANG_EMAIL, 'email');

            // Не отправляли ничего
            if (!$sended || $verify_hours_exp === true || !empty($sended['accepted'])) {

                if ($show_email_field) {

                    $form->addField('email', new fieldString('new_email', [
                        'title' => LANG_EMAIL_NEW,
                        'hint'  => LANG_EMAIL_NEW_HINT,
                        'type'  => 'email',
                        'rules' => [
                            ['email'],
                            [function ($controller, $data, $value)use ($profile) {

                                if (!$value) { return true; }

                                $exists = $controller->model->getItemByField('{users}', 'email', $value);

                                if ($exists) {
                                    return LANG_REG_EMAIL_EXISTS;
                                }

                                return true;
                            }]
                        ]
                    ]));
                }
            } else {
                $form->addField('email', new fieldString('new_email_confirm_hash', [
                    'title' => LANG_EMAIL_NEW_HASH,
                    'rules' => [
                        ['required']
                    ]
                ]));
            }
        }

        $data = [
            '2fa' => $profile['2fa'],
            'new_email_confirm_hash' => $this->request->get('new_email_confirm_hash', '')
        ];

        if ($this->request->has('submit')) {

            $data = $form->parse($this->request, true);

            $errors = $form->validate($this, $data);

            if (!$errors) {

                $success_text = [LANG_SUCCESS_MSG];

                list($profile, $data, $form) = cmsEventsManager::hook('users_before_edit_password', [$profile, $data, $form]);

                $profile = array_merge($profile, $data);

                // если запрашивали смену email
                if (!empty($data['new_email'])) {

                    $verify_data = [
                        'email'     => $data['new_email'],
                        'timestamp' => time(),
                        'hash'      => string_random()
                    ];

                    // На новый email
                    cmsUser::setUPS($ups_key, $verify_data);

                    // письмо на новый email
                    $this->controller_messages->sendEmail(['email' => $data['new_email'], 'name' => $profile['nickname']], ['name' => 'email_verify'], [
                        'nickname'    => $profile['nickname'],
                        'page_url'    => href_to_profile($profile, ['edit', 'password'], true) . '?new_email_confirm_hash=' . $verify_data['hash'],
                        'hash'        => $verify_data['hash'],
                        'valid_until' => html_date(date('d.m.Y H:i', time() + ($this->verify_exp * 3600)), true)
                    ]);

                    $success_text[] = sprintf(LANG_USERS_EMAIL_VERIFY, $data['new_email']);
                }

                // Пришло подтверждение
                if (!empty($data['new_email_confirm_hash'])) {

                    if ($sended['hash'] === $data['new_email_confirm_hash']) {

                        $verify_data_old = [
                            'accepted'  => 1,
                            'email'     => $profile['email'],
                            'timestamp' => time(),
                            'hash'      => string_random()
                        ];

                        // На старый email
                        cmsUser::setUPS('users.change_email_' . md5($sended['email']), $verify_data_old);

                        // уведомление на старый
                        $this->controller_messages->sendEmail(
                            ['email' => $profile['email'], 'name' => $profile['nickname']],
                            ['name' => 'email_verify_notice'],
                            ['nickname'  => $profile['nickname'], 'new_email' => $sended['email']]
                        );

                        $profile['email'] = $sended['email'];
                    } else {

                        $errors['new_email_confirm_hash'] = LANG_CONFIRM_CODE_ERROR;
                    }
                }

                if (!$errors) {

                    $result = $this->model->updateUser($profile['id'], $profile);

                    if ($result['success']) {

                        list($profile, $data, $form) = cmsEventsManager::hook('users_after_edit_password', [$profile, $data, $form]);

                        if (!empty($data['password1'])) {
                            $success_text[] = LANG_PASS_CHANGED;
                        }

                        foreach ($success_text as $stext) {
                            cmsUser::addSessionMessage($stext, 'success');
                        }

                        $this->redirectTo('users', $profile['id']);

                    } else {
                        $errors = $result['errors'];
                    }
                }
            }

            if ($errors) {
                cmsUser::addSessionMessage(LANG_FORM_ERRORS, 'error');
            }
        }

        return $this->cms_template->render('profile_edit_password', [
            'id'      => $profile['id'],
            'profile' => $profile,
            'data'    => $data,
            'form'    => $form,
            'errors'  => $errors ?? false
        ]);
    }

}
