<?php

namespace apexl\Io\modules\userDisplay\controllers;

use apexl\Io\includes\Controller;
use apexl\Io\includes\Hook;
use apexl\Io\includes\Routes;
use apexl\Io\includes\System;
use apexl\Io\modules\company\entities\companyEntity;
use apexl\Io\modules\display\components\BasicLink;
use apexl\Io\modules\display\components\ButtonBar;
use apexl\Io\modules\display\components\CardEntityFilteredDisplayTable;
use apexl\Io\modules\display\components\ColWrapper;
use apexl\Io\modules\display\components\ContentTitle;
use apexl\Io\modules\display\components\defaultWrapper;
use apexl\Io\modules\display\components\DisplayTable;
use apexl\Io\modules\display\components\EntityFilteredDisplayTable;
use apexl\Io\modules\display\components\FormComponent;
use apexl\Io\modules\display\components\genericComponents;
use apexl\Io\modules\display\components\RowWrapper;
use apexl\Io\modules\display\services\Render;
use apexl\Io\modules\formbuilder\entities\formEntity;
use apexl\Io\modules\formbuilder\includes\checkboxField;
use apexl\Io\modules\formbuilder\includes\inputField;
use apexl\Io\modules\formbuilder\includes\markupField;
use apexl\Io\modules\formbuilder\includes\selectField;
use apexl\Io\modules\subscription\entities\subscriptionEntity;
use apexl\Io\modules\subscriptionDisplay\components\viewTiles;
use apexl\Io\modules\user\entities\userContactDetailsEntity;
use apexl\Io\modules\userDisplay\components\dashboardTiles;
use apexl\Io\modules\userDisplay\components\roleEntityDisplayTile;
use apexl\Io\modules\userDisplay\components\userEntityDisplayTile;
use apexl\Io\modules\userDisplay\forms\forgottenPasswordForm;
use apexl\Io\modules\userDisplay\forms\loginAsUserForm;
use apexl\Io\modules\userDisplay\forms\loginForm;
use apexl\Io\modules\user\entities\roleEntity;
use apexl\Io\modules\user\entities\userEntity;
use apexl\Io\modules\user\services\currentUser;
use apexl\Io\services\Output;
use apexl\Io\staticData\countries;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class userController extends Controller
{
    protected $currentUser;
    protected $render;

    public function __construct(Render $render, currentUser $currentUser)
    {
        parent::__construct();
        $this->currentUser = $currentUser::getCurrentUser();
        $this->render = $render;
    }

    /**
     * @param Request $request
     * @param Response $response
     * @param $args
     * @return Response
     * @throws \Exception
     */
    public function userViewSingle(Request $request, Response $response, $args)
    {

        $userEntity = userEntity::load($args['id']);

        $rowWrapper = (new RowWrapper())->addClass('manageForm-wrapper');
        $rowWrapper->addComponent(dashboardTiles::userDetailsTile($args['id']));

        $rowWrapper->addComponent(\apexl\Io\modules\invoiceDisplay\components\dashboardTiles::userInvoicesTile($userEntity));
        $rowWrapper->addComponent(viewTiles::userSubscriptionsTile($userEntity));



        $buttonsBar = new ButtonBar();
        $buttonsBar->setEntity($userEntity);

        $this->render::setPageTitle('Viewing ['.$userEntity->id.'] - '.$userEntity->getNiceName());

        return System::asJson($response, $this->render::build([$buttonsBar, $rowWrapper]));
    }

    /**
     * @param Request $request
     * @param Response $response
     * @return Response
     */
    public function userSettingsPage(Request $request, Response $response)
    {
        $form = (new FormComponent())
            ->src(Routes::getRoutePattern('user.display.forms.userSettings'))
            ->setID('register');

        $this->render::setPageTitle('User Settings');

        return System::asJson($response, $this->render::build([$form]));
    }

    /**
     * @param Request $request
     * @param Response $response
     * @return Response
     * @throws \Exception
     */
    public function userSettingsForm(Request $request, Response $response)
    {
        return $this->userEditForm($request, $response, ['id' => $this->currentUser->id]);
    }

    public function resetPasswordForm(Request $request, Response $response, $args)
    {
        $form = new formEntity();
        $form->setId('reset-password-form');
        $form->setSubmitText('Reset Password Now');
        $form->setMethod('post');
        $form->setActionUrl(Routes::getRoutePattern('user.resetPassword'));
        $form->addField((new inputField('password'))->setLabel('Password')->setPlaceholder('Password')->setInputType('password')->addValidation("minLength", ["min" => 6])->isRequired());
        $form->addField((new inputField('confirm_password'))->setLabel('Confirm Password')->setPlaceholder('Confirm Password')->setInputType('password')->addValidation("minLength", ["min" => 6])->isRequired());
        $form->addField((new inputField('hash'))->setInputType('hidden')->setValue($args['hash'])->isRequired());

        return System::asJson($response, $form->getBuiltFormArray());
    }

    public function resetPasswordPage(Request $request, Response $response, $args)
    {
        $this->render::setActive("noUI");
        $this->render::setMetaTitle("Forgotten Password | ". ($this->config->app->defaultMetaTitle ?? "Io Dashboard"));

        $hash = $args['hash'] ?? false;
        $valid = false;
        if ($hash) {
            $user = new userEntity();
            $match = $user->getForgottenPasswordLink($hash);
            if (!empty($match) && ((time() - $match['created']) <= 86400 && $match['used'] == 0)) {
                $valid = true;
                $rowWrapper = (new RowWrapper())->addClass('d-block');
                $rowWrapper->addComponent(
                    (new FormComponent())
                        ->src(Routes::getRoutePattern('user.display.forms.resetPassword', ['hash' => $hash]))
                        ->title("Reset your password using the fields below:")
                        ->addClass('forgotten-password-form')->setID('forgottenPassword')
                );
                $rowWrapper->addComponent(
                    (new BasicLink())->addClass('forgottenPasswordLink return mt-5 text-decoration-underline')->addRoute(Routes::getRoutePattern('user.display.login'))->addText(System::getVariable('user_login_return_login_text') ?? 'Return to login')
                );
            }
        }

        if (!$valid) {
            $rowWrapper = (new ColWrapper())
                ->addClass('forgotten-password-form text-center')
                ->addComponents([
                    (new ContentTitle())->addTitle('Your reset link has expired')->addContent('Please request a new password reset link using the button below:')->addClass('mb-5'),
                    (new BasicLink())->addClass('btn btn-primary')->addText('Go to Password Reset')->addRoute(Routes::getRoutePattern('user.display.forgot-password'))
                ]);
        }

        $this->output::addResponse($request, $this->render::build([$rowWrapper]));

        return System::asJson($response);
    }

    public function resetPasswordSuccess(Request $request, Response $response, $args)
    {
        $this->render::setActive("noUI");
        $this->render::setMetaTitle("Your password has been reset | ". ($this->config->app->defaultMetaTitle ?? "Io Dashboard"));

        $rowWrapper = (new ColWrapper())
            ->addClass('forgotten-password-form text-center')
            ->addComponents([
                (new ContentTitle())->addTitle('Password reset successful')->addContent('Please login to the site using your new credentials:')->addClass('mb-5'),
                (new BasicLink())->addClass('btn btn-primary')->addText('Go to login page')->addRoute(Routes::getRoutePattern('user.display.login'))
            ]);


        $this->output::addResponse($request, $this->render::build([$rowWrapper]));

        return System::asJson($response);
    }

    /**
     * Login page - @see userDisplayController in io-user
     * @param Request $request
     * @param Response $response
     * @return Response
     */
    public function loginPage(Request $request, Response $response, $args)
    {
        if (currentUser::getCurrentUser()->isLoggedIn()) {
            Output::addMetadata('user.login.redirect', 'redirect', '/');
            return System::asJson($response);
        }

        $this->render::setActive("noUI");
        $this->render::setMetaTitle("Login | ". ($this->config->app->defaultMetaTitle ?? "Io Dashboard"));
        $components = [];
        if (isset($args['loginMessageType']) && isset($this->config->app->loginMessageTypes->{$args['loginMessageType']})) {
            $components[] = (new ContentTitle())->addContent($this->config->app->loginMessageTypes->{$args['loginMessageType']})->addClass('text-light');
        }
        $components[] = (new defaultWrapper())
            ->addComponent(
                (new FormComponent())->src(Routes::getRoutePattern('user.display.forms.login'))
            ->title(System::getVariable('user_login_description_text') ?? "Sign in with your email address.")
                    ->addClass('login-form')->setID('login')
            )
            ->addComponent(
                (new BasicLink())->addClass('forgottenPasswordLink')->addRoute(Routes::getRoutePattern('user.display.forgot-password'))->addText(System::getVariable('user_login_forgot_password_text') ?? 'Forgot password?')
            )
            ->addComponent(
                (new defaultWrapper())
                    ->addClass('d-flex justify-content-center')
                    ->addComponent(
                        (new BasicLink())->addClass('registerLink mt-5 btn')->addRoute(Routes::getRoutePattern(System::getVariable('user_registration_route') ?? 'user.display.register'))->addText(System::getVariable('user_login_register_text') ?? 'No account? Register.')
                    )

            );

        return System::asJson($response, $this->render::build($components));
    }

    public function registerPage(Request $request, Response $response, $args)
    {
        if (currentUser::getCurrentUser()->isLoggedIn()) {
            Output::addMetadata('user.login.redirect', 'redirect', '/');
            return System::asJson($response);
        }

        $this->render::setActive("noUI");
        $this->render::setMetaTitle("Register | ". ($this->config->app->defaultMetaTitle ?? "Io Dashboard"));
        $components = [];

        $components[] = (new FormComponent())->src(Routes::getRoutePattern('user.display.forms.register'))
            ->title(System::getVariable('user_register_description_text') ?? "Register an account.")
            ->addClass('register-form')->setID('register');
        $components[] = (new BasicLink())
            ->addClass('loginLink')
            ->addRoute(Routes::getRoutePattern('user.display.login'))
            ->addText(System::getVariable('user_register_login_text') ?? 'Got an account? Log in.');

        return System::asJson($response, $this->render::build($components));
    }

    /**
     * @param Request $request
     * @param Response $response
     * @return Response
     */
    public function loginForm(Request $request, Response $response, $args)
    {
        return System::asJson($response, (new loginForm())->loginForm($args));
    }

    public function loginAsUserForm(Request $request, Response $response, $args){
        return System::asJson($response, (new loginAsUserForm())->loginAsUserForm($args));
    }

    public function manageSettingsForm(Request $request, Response $response, $args)
    {
        $currentUser = currentUser::getCurrentUser();
        $form = new formEntity();
        $form->setId('user-manage-settings-form');
        $form->setSubmitText('Update Now');
        $form->setMethod('post');
        $form->setActionUrl(Routes::getRoutePattern('user.updateSettings'));
        $settings = $currentUser->settings ?? null;
        $minOptions = [
            0 => 'Disabled',
            5 => '5 mins',
            10 => '10 mins',
            20 => '20 mins',
            20 => '30 mins',
            60 => '60 mins'
        ];
        $form->addField((new markupField("systemSettingsTitle"))->setValue("<h4>System Settings</h4>"));
        $form->addField((new selectField('logoutAfterInactivity', $minOptions))->setLabel('Logout after inactivity')->setValue($settings->logoutAfterInactivity ?? 0));
        $form->addField((new selectField('refreshScreenContentEvery', $minOptions))->setLabel('Refresh Screen Content Every')->setValue($settings->refreshScreenContentEvery ?? 0));
        $form->addField((new checkboxField('displayNotificationsOnScreen'))->setLabel('Display notifications on screen')->setValue($settings->displayNotificationsOnScreen ?? 0));
        $form->addField((new markupField("cookieSettings"))->setValue("<h4>Cookie Settings</h4>"));
        $form->addField((new checkboxField('allowTrackingCookies'))->setLabel('Allow tracking cookies')->setValue($settings->allowTrackingCookies ?? 1));
        $form->addField((new markupField("usefulLinks"))->setValue("<h4>Useful Links</h4>"));
        if ($href = System::getVariable('settings_contact_support_href')) {
            $form->addField((new markupField("usefulLinks_contactSupport"))->setValue('<i class="fa-regular fa-circle-question"></i> <a target="_blank" href="'.$href.'">Contact Support</a>'));
        }
        if ($href = System::getVariable('settings_report_a_bug_href')) {
            $form->addField((new markupField("usefulLinks_reportABug"))->setValue('<i class="fa-light fa-bug"></i> <a target="_blank" href="'.$href.'">Report a Bug</a>'));
        }
        if ($href = System::getVariable('settings_visit_website_href')) {
            $form->addField((new markupField("usefulLinks_visitWebsite"))->setValue('<i class="fa-light fa-arrow-right"></i> <a target="_blank" href="'.$href.'">Visit Website</a>'));
        }

        return System::asJson($response, $form->getBuiltFormArray());

    }

    /**
     * Forgotten Password Page
     * @param Request $request
     * @param Response $response
     * @return Response
     */
    public function forgotPasswordPage(Request $request, Response $response)
    {
        if (currentUser::getCurrentUser()->isLoggedIn()) {
            Output::addMetadata('user.login.redirect', 'redirect', '/');

            return System::asJson($response);
        }
        $this->render::setActive("noUI");
        $this->render::setMetaTitle("Forgotten Password | ". ($this->config->app->defaultMetaTitle ?? "Io Dashboard"));

        $rowWrapper = (new RowWrapper())->addClass('d-block');
        $rowWrapper->addComponent(
            (new FormComponent())->src(Routes::getRoutePattern('user.display.forms.forgottenPassword'))
            ->title("Enter your email to reset your password.")
                ->addClass('forgotten-password-form')->setID('forgottenPassword')
        );
        $rowWrapper->addComponent(
            (new BasicLink())->addClass('forgottenPasswordLink return mt-5 text-decoration-underline')->addRoute(Routes::getRoutePattern('user.display.login'))->addText(System::getVariable('user_login_return_login_text') ?? 'Return to login')
        );

        $this->output::addResponse($request, $this->render::build([$rowWrapper]));

        return System::asJson($response);
    }

    /**
     * @param Request $request
     * @param Response $response
     * @return Response
     */
    public function forgotPasswordCheckEmail(Request $request, Response $response)
    {
        $this->render::setActive("noUI");
        $this->render::setMetaTitle("Check Email | ". ($this->config->app->defaultMetaTitle ?? "Io Dashboard"));

        $rowWrapper = (new RowWrapper())->addClass('d-block');
        $rowWrapper->addComponent(
            (new ContentTitle())
            ->addContent("Please check your email for further instructions. The email may take upto a few minutes to arrive.")
            ->addClass('text-white forgot-password-email-message')
                ->setColWidth('md', 12)->setID('forgottenPassword')
        );
        $rowWrapper->addComponent(
            (new BasicLink())->addClass('forgottenPasswordLink return mt-5 text-decoration-underline')->addRoute(Routes::getRoutePattern('user.display.login'))->addText(System::getVariable('user_login_return_login_text') ?? 'Return to login')
        );

        $this->output::addResponse($request, $this->render::build([$rowWrapper]));
        return System::asJson($response);
    }

    /**
     * @param Request $request
     * @param Response $response
     * @return Response
     */
    public function forgotPasswordForm(Request $request, Response $response)
    {
        return System::asJson($response, (new forgottenPasswordForm())->forgottenPasswordForm());
    }

    /**
     * @param Request $request
     * @param Response $response
     * @return Response
     */
    public function registerForm(Request $request, Response $response)
    {
        $form = $this->primaryAccountForm(true);
        return System::asJson($response, $form->getBuiltFormArray());
    }

    /**
     * @param Request $request
     * @param Response $response
     * @param array $args
     * @return Response
     * @throws \Exception
     */
    public function userEditForm(Request $request, Response $response, $args = [])
    {

        //set form field values
        $user = new userEntity();
        $routeData = [];
        if (isset($args[$user->primaryKey])) {
            $user->load($args[$user->primaryKey]);
            $routeData['id'] = $user->id;
        }

        $form = $this->primaryAccountForm(false, $user);

        // Admin functionality
        if ($this->currentUser->isAllowed('ChangeUserActiveState')) {
            $form->setFieldsetSetting('admin_options', 'fieldset_legend', 'Administrator Options');

            $form->addFieldToGroup((new checkboxField('active'))->setLabel('Active (Can Login)')->setValue(isset($user->active) ? $user->active == 1 : false), 'Administration', 'admin_options');
            $form->addFieldToGroup((new checkboxField('suspended'))->setLabel('Suspended')->setValue(isset($user->suspended) ? $user->suspended == 1 : false), 'Administration', 'admin_options');
            $form->addFieldToGroup((new checkboxField('marked_fraudulent'))->setLabel('Marked as Fraudulent')->setValue(isset($user->marked_fraudulent) ? $user->marked_fraudulent == 1 : false), 'Administration', 'admin_options');
            $form->addFieldToGroup((new inputField('invoice_name_override'))->setLabel('Invoice Name Override')->setValue(isset($user->invoice_name_override) ? $user->invoice_name_override : null), 'Administration', 'admin_options');

            $roles = (new roleEntity())->loadMultiple();
            foreach ($roles as $role) {
                //for users that can't change roles, show labels for those that they do have.
                $showLabel = false;
                if ($this->currentUser->isAllowed('UpdateRoles') || $this->currentUser->isAllowed('AssignRole_'.$role->id)) {
                    $roleField = (new checkboxField('role_' . $role->id))->setLabel($role->name);
                } else {
                    $showLabel = true;
                    $roleField = (new inputField('role_' . $role->id));
                    $roleField->setInputType('hidden');
                }
                if (($user->id ?? false) && is_array($user->roles) && ($user && in_array($role->id, $user->roles))) {
                    //allows us to show the label only for those without the role to change.
                    //Only shows labels for the roles they have.
                    if ($showLabel) {
                        $roleField->setLabel($role->name);
                    }
                    $roleField->setValue($role->id);
                }
                $form->addFieldToGroup($roleField, 'Administration', 'admin_options');
            }
        }

        $form->setActionUrl(Routes::getRoutePattern('userEntity.put', $routeData));
        $form->setSubmitText('Update Now');

        if ($this->config->app->user->useContactDetails ?? null) {
            $userContactDetailsEntity = new userContactDetailsEntity();
            if ($user->id) {
                $userContactDetailsEntity->load($user->id);
            }
            $form->setFieldsetSetting('your_address', 'fieldset_legend', 'Your Shipping Address');
            //$form->addFieldToGroup((new inputField('company_name'))->setLabel('Company Name:'), 'Your Address', 'your_address');
            $form->addFieldToGroup((new inputField('shipping_address_1'))->setLabel('Address line 1:*')->setValue($userContactDetailsEntity->shipping_address_1 ?? '')->isRequired(), 'Your Address', 'your_address');
            $form->addFieldToGroup((new inputField('shipping_address_2'))->setLabel('Address line 2:*')->setValue($userContactDetailsEntity->shipping_address_2 ?? '')->isRequired(), 'Your Address', 'your_address');
            $form->addFieldToGroup((new inputField('shipping_address_3'))->setLabel('Address line 3:')->setValue($userContactDetailsEntity->shipping_address_3 ?? ''), 'Your Address', 'your_address');
            $form->addFieldToGroup((new inputField('shipping_town'))->setLabel('Town/City:*')->setValue($userContactDetailsEntity->shipping_town ?? '')->isRequired(), 'Your Address', 'your_address');
            $form->addFieldToGroup((new inputField('shipping_county'))->setLabel('County/State:*')->setValue($userContactDetailsEntity->shipping_county ?? '')->isRequired(), 'Your Address', 'your_address');
            $form->addFieldToGroup((new inputField('shipping_postcode'))->setLabel('Postcode/Zip:*')->setValue($userContactDetailsEntity->shipping_postcode ?? '')->isRequired(), 'Your Address', 'your_address');
            $countries = countries::getAllCountries();
            $options = [];
            $options[''] = "Select One";
            foreach ($countries as $country) {
                $options[$country['key']] = $country['value'];
            }
            $form->addFieldToGroup((new selectField('shipping_country', $options))->setLabel('Country:*')->setValue($userContactDetailsEntity->shipping_country ?? ''), 'Your Address', 'your_address');

            $form->setFieldsetSetting('billing_address', 'fieldset_legend', 'Billing Address');
            $form->addFieldToGroup((new checkboxField('same_address'))->setLabel('My delivery and billing addresses are the same.')->setValue($userContactDetailsEntity->same_address), 'Billing Address', 'billing_address');
            //$form->addFieldToGroup((new inputField('billing_company_name'))->setLabel('Company Name:'), 'Billing Address', 'billing_address');
            $form->addFieldToGroup((new inputField('billing_address_1'))->setLabel('Address line 1:')->setValue($userContactDetailsEntity->billing_address_1 ?? ''), 'Billing Address', 'billing_address');
            $form->addFieldToGroup((new inputField('billing_address_2'))->setLabel('Address line 2:')->setValue($userContactDetailsEntity->billing_address_2 ?? ''), 'Billing Address', 'billing_address');
            $form->addFieldToGroup((new inputField('billing_address_3'))->setLabel('Address line 3:')->setValue($userContactDetailsEntity->billing_address_3 ?? ''), 'Billing Address', 'billing_address');
            $form->addFieldToGroup((new inputField('billing_town'))->setLabel('Town/City:')->setValue($userContactDetailsEntity->billing_town ?? ''), 'Billing Address', 'billing_address');
            $form->addFieldToGroup((new inputField('billing_county'))->setLabel('County/State:')->setValue($userContactDetailsEntity->billing_county ?? ''), 'Billing Address', 'billing_address');
            $form->addFieldToGroup((new inputField('billing_postcode'))->setLabel('Postcode/Zip:')->setValue($userContactDetailsEntity->billing_postcode ?? ''), 'Billing Address', 'billing_address');
            $form->addFieldToGroup((new selectField('billing_country', $options))->setLabel('Country:')->setValue($userContactDetailsEntity->billing_country ?? ''), 'Billing Address', 'billing_address');
        }




        //allow other modules to add form fields.
        $form = Hook::processHook('displayFormRender', $form, $user, 'userEditForm');


        //set role values
        $this->output::addResponse($request, $form->getBuiltFormArray());
        return System::asJson($response);
    }

    protected function primaryAccountForm($passwordRequired = false, $userEntity): formEntity
    {
        $form = new formEntity();
        $form->setId('user-account-form');
        $form->addClass('user-account-form');
        $form->setMethod('post');
        if ($userEntity->id ?? null) {
            $form->setActionUrl(Routes::getRoutePattern($userEntity->getEntityName() . '.put', ['id' => $userEntity->id]));
            $form->setMethod('PUT');
        } else {
            $form->setActionUrl(Routes::getRoutePattern('userEntity.post'));
        }
        $form->setFieldsetSetting('primary_account', 'fieldset_legend', 'About You');
        $form->addFieldToGroup((new inputField('first_name'))->setLabel('First Name')->setPlaceholder('First Name')->setValue($userEntity->first_name ?? '')->isRequired(), 'About You', 'primary_account');
        $form->addFieldToGroup((new inputField('last_name'))->setLabel('Surname')->setPlaceholder('Surname')->setValue($userEntity->last_name ?? '')->isRequired(), 'About You', 'primary_account');
        $form->addFieldToGroup((new inputField('email'))->setLabel('Email')->setPlaceholder('Email')->setInputType('email')->setValue($userEntity->email ?? '')->isRequired(), 'About You', 'primary_account');

        if (class_exists('apexl\Io\modules\company\entities\companyEntity')) {
            $companyEntity = new companyEntity();
            if (!$this->currentUser->isAllowed('administer')) {
            if ($userEntity->id) {
                $companyEntity->loadByUser($userEntity->id);
                $form->addFieldToGroup((new inputField('company_name'))->setLabel('Company Name')->setPlaceholder('Company Name')->setValue($companyEntity->CompanyName ?? null)->isRequired(), 'About You', 'primary_account');
            } else {
                    $companyEntity->loadByUser($this->currentUser->id);
                    if (isset($companyEntity->id) && $companyEntity->id > 0) {
                        $form->addFieldToGroup((new inputField('company'))->setValue($companyEntity->id ?? 0)->setInputType('hidden'), 'About You', 'primary_account');
                    } else {
            $form->addFieldToGroup((new inputField('company_name'))->setLabel('Company Name')->setPlaceholder('Company Name')->setValue($companyEntity->CompanyName ?? null)->isRequired(), 'About You', 'primary_account');
                    }
                }
            }

        }
        if ($this->config->app->user->useContactDetails ?? null) {
            if ($userEntity->id) {
                $userContactDetailsEntity = new userContactDetailsEntity();
                $userContactDetailsEntity->load($userEntity->id);
            }
            $form->addFieldToGroup((new inputField('phone'))->setLabel('Phone')->setPlaceholder('Phone')->setValue($userContactDetailsEntity->phone ?? '')->isRequired(), 'About You', 'primary_account');
        }

        $form->setFieldsetSetting('password_reset', 'password_reset', 'Your Credentials');
        $password = (new inputField('password'))->setLabel('Password')->setPlaceholder('Password')->setInputType('password')->addValidation("minLength", ["min" => 6]);
        $confirmPass = (new inputField('confirm_password'))->setLabel('Confirm Password')->setPlaceholder('Confirm Password')->setInputType('password')->addValidation("minLength", ["min" => 6]);
        if ($passwordRequired) {
            $password->isRequired();
            $confirmPass->isRequired();
        }
        $form->addFieldToGroup($password, 'Your Credentials', 'password_reset');
        $form->addFieldToGroup($confirmPass, 'Your Credentials', 'password_reset');

        return $form;
    }

    /**
     * @param Request $request
     * @param Response $response
     * @return Response
     */
    public function userHome(Request $request, Response $response)
    {
        $rowWrapper = (new RowWrapper())->setColWidth('sm', 12)->addClass('manageForm-wrapper');
        $rowWrapper->setColWidth('sm', 12)->addClass('manageForm-wrapper');
        $rowWrapper->addComponent(new userEntityDisplayTile());
        if ($this->currentUser->isAllowed('ViewRoles')) {
            $rowWrapper->addComponent(new roleEntityDisplayTile());
        }

        $this->render::setPageTitle('User Dashboard');
        $this->output::addResponse($request, $this->render::build([$rowWrapper]));
        return System::asJson($response);
    }

    /**
     * @param Request $request
     * @param Response $response
     * @return Response
     * @throws \Exception
     */
    public function userList(Request $request, Response $response)
    {
        $buttonBar = new ButtonBar();
        $buttonBar->setEntity((new userEntity()), 'List');

        $helpComponents = [
            (new ContentTitle())->addClass('text-black text-start help-modal-content-title')->addTitle('A list of Users, and their details'),
            (new DisplayTable())->addClass('text-black text-start help-modal-display-table')->addRows([
                ['ID', 'Unique user reference'],
                ['Name', 'Customer name'],
                ['Validated/Active', 'Whether the user is marked as validated. This affects whether a user can log in'],
                ['Email Address', 'Customer email address'],
                ['Company', 'Company Name'],
                ['Last Login', 'Date and Time of Last Login'],
                ['Created', 'Date this user was created'],
                ['Roles', 'Data access roles belonging to this user'],
            ])
        ];

        $table = (new CardEntityFilteredDisplayTable(new userEntity(), [], true, 'dropmenu'))
            ->addTitle('Users')
            ->src(Routes::getRoutePattern('userEntity.get'))
            ->displayPagination()
            ->hideIdColumn()
            ->addProperty('refreshButton', '<i class="fa-light fa-arrows-rotate"></i>')
        //$table->setFilters('orderBy[]=missing_sims&orderBy[]=DESC&orderBy[]=subscription.id&orderBy[]=DESC');
            ->addFilterForm('user.display.forms.filters.userFilter', null, 5, true, 'Filter Users')
            ->addHeaderModal('Users List Table', $helpComponents);

        $table = Hook::processHook('user_list_table_modify', $table);

        //render
        $this->render::setPageTitle('Users');
        $this->output::addResponse($request, $this->render::build([$buttonBar, $table]));
        return System::asJson($response);
    }

    public function create(Request $request, Response $response, $args)
    {
        $title = 'Create new user';
        if ($id = $args['id'] ?? false) {
            $user = new userEntity();
            $user->load($id);
            $title = 'Update ' . $user->getNiceName();
        }

        $form = (new FormComponent())->setID('userCreate')->src(Routes::getRoutePattern('user.display.forms.createUpdate', $args));
        $this->render::setPageTitle($title);
        $this->output::addResponse($request, $this->render::build([genericComponents::dashboardBlockWrapper([$form])]));
        return System::asJson($response);
    }

    /**
     * @param Request $request
     * @param Response $response
     * @param array $args
     * @return Response
     * @throws \Exception
     */
    public function updateView(Request $request, Response $response, $args = [])
    {
        $title = 'Create a user';
        if ($id = $args['id'] ?? false) {
            $userEntity = new userEntity();
            $userEntity->load($id);
            $title = 'Edit ('.$id.') '. $userEntity->getNiceName();
        }

        $form = (new FormComponent())->setID('roleCreate')->src(Routes::getRoutePattern('user.display.forms.createUpdate', $args));
        $this->render::setPageTitle($title);
        $this->output::addResponse($request, $this->render::build($form));
        return System::asJson($response);
    }

    public function suspendUser(Request $request, Response $response, $args = [])
    {
        $userEntity = new userEntity();
        $userEntity->load($args['id']);
        if (!isset($userEntity->id)) {
            return System::asJson($response, [], 404);
        }

        $contentTitle = (new ContentTitle())
            ->addTitle('Are you sure?')
            ->addContent($userEntity->first_name . ' will no longer be able to log in, and any payment subscriptions they have will be suspended')
            ;
        $suspendTile = dashboardTiles::suspendUserTile($userEntity);
        $components = [$contentTitle, $suspendTile];

        $components = Hook::processHook('suspendUserPopupContent', $components, $userEntity);

        $rowWrapper = (new RowWrapper())
            ->addComponent((new ColWrapper())
                ->addComponents($components)
            );

        $this->render::setActive("modal");
        $this->output::addResponse($request, $this->render::build($rowWrapper));

        return System::asJson($response);
    }

    /**
     * @param bool $passwordRequired
     * @return formEntity
     */


    /**
     * @param Request $request
     * @param Response $response
     * @param $args
     * @return Response
     */
    public function userSummery(Request $request, Response $response, $args)
    {
        $structure = [
            'tableHeader' => [
                'User ID',
                'Name',
                'Active',
                'Email',
                'Last Logged In',
                'Roles'
            ],
            'fields' => [
                'id',
                'first_name',
                'active',
                'email',
                'last_login',
                'roles'
            ],
            'callables' => [
                'field__last_login' => function ($key, $entityId, $row) : string {
                    return \apexl\Io\modules\userDisplay\callbacks\tableRowAlters::userShortTable($key, $entityId, $row);
                },
                'field__first_name' => function ($key, $entityId, $row) : string {
                    return \apexl\Io\modules\userDisplay\callbacks\tableRowAlters::userShortTable($key, $entityId, $row);
                },
                'field__roles' => function ($key, $entityId, $row) : string {
                    return \apexl\Io\modules\userDisplay\callbacks\tableRowAlters::userShortTable($key, $entityId, $row);
                }
            ]
        ];
        return $this->getEntityData($request, $response, $args, (new userEntity()), [], $structure);
    }
}
