import qrcode from 'corcojs-qrcode';
import notify from 'notify';
import rbac from '../../rbac';

angular.module('profilesDirectivesModule', [])
    .directive('twoFaSetup', ['profileService', '$rootScope', function (profileService, $rootScope) {
        return {
            templateUrl: MP_SITE_URL + '/directives/partials/twoFaSetup.php',
            restrict: 'A',
            scope: {
                identifier: '=',
            },

            link: function ($scope) {

                const typeNumber = 0; // automatic type number
                const errorCorrectionLevel = 'L'; // low

                $scope.data = {};

                // only users who can manage settings can make 2FA mandatory in Preferences
                $scope.canManageSettings = false;
                rbac.isActionAllowed('settings.manage').then(allowed => {
                    console.log('canManageSettings', allowed);
                    $scope.canManageSettings = allowed;
                    $scope.$applyAsync();
                });

                const reset = () => {
                    $scope.configureInProcess = false;
                    $scope.data.code = '';
                };

                $scope.cancel = reset;

                const loadUser = () => {
                    profileService.getUser().then(({data} = response) => {
                        $scope.user = data;
                    });
                };

                loadUser();

                $scope.$watch('user', user => {
                    $scope.data.twoFaCheckEnabled = user?.two_factor_enabled;
                    // keep the dashboard/profile 2FA warning in sync when 2FA is enabled or disabled here
                    if (user) {
                        $rootScope.showTwoFaNotification = !user.two_factor_enabled;
                    }
                });

                $scope.enable = function () {
                    $scope.configureInProcess = true;
                    profileService.configureTwoFa().then(({data} = response) => {
                        $scope.twoFaUrl = data['2faUrl'];
                        $scope.twoFaSecret = data['secret'];
                    });
                }

                $scope.disable = function (event) {
                   if ($scope.user?.two_factor_enabled) {
                       // prevent checkbox being unselected until the real 2FA disabling happened
                       event.preventDefault();
                       twoFa.asyncCheck2FaVerificationValid().then(() =>
                           profileService.disableTwoFa($scope.data.code).then(
                               () => {
                                   loadUser();
                                   reset();
                                   notify.success('Two-factor authentication successfully disabled.');
                               },
                               err => {
                                   notify.error(err.data);
                               }),
                           () => {}
                       );
                   }

                    if ($scope.configureInProcess) {
                        $scope.configureInProcess = false;
                        return;
                    }
                }

                $scope.verify = function () {
                    profileService.verifyTwoFaConfiguration($scope.data.code).then(
                        () => {
                            loadUser();
                            reset();
                            notify.success('Two-factor authentication successfully configured.');
                        },
                        err => {
                            notify.error(err.data.trim());
                        });
                }

                $scope.$watch('twoFaUrl', twoFaUrl => {
                    if (!twoFaUrl) return;
                    const qr = qrcode(typeNumber, errorCorrectionLevel);
                    qr.addData(twoFaUrl);
                    qr.make();
                    document.getElementById('canvas').innerHTML = qr.createImgTag(4);
                });
                
                // cancel configuration on Escape press
                document.addEventListener('keydown', function(event) {
                    if ((event.key === 'Escape' || event.keyCode === 27) && $scope.configureInProcess) {
                        $scope.configureInProcess = false;
                        $scope.data.twoFaCheckEnabled = false;
                        $scope.data.code = '';
                        $scope.$apply();
                    }
                });
            }
        };
    }])
    .directive('enterPress', function () {
        return function (scope, element, attrs) {
            element.bind('keypress', function (event) {
                if (event.which === 13) {
                    scope.$apply(function () {
                        scope.$eval(attrs.enterPress);
                    });
                    event.preventDefault();
                }
            });
        };
    })
