<template>
    <div>
        <h1>ECG account</h1>
        <h2>⚿ Set new password</h2>

        <div v-if="validationRequestActive" class="alert alert-info">
            Validating password reset token …
            <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
        </div>
        <template v-else>


            <div v-if="!tokenIsValid" class="alert alert-danger" role="alert">
                <template v-if="validationRequestError">
                    <h3>Failed to validate password reset token</h3>
                    <p>{{ validationRequestError }}</p>
                </template>
                <template v-else>
                    <h3>Invalid token provided</h3>
                    <p>This password reset token isn't valid (anymore). Please
                    <router-link :to="{ name: 'request' }" tag="a">send the password reset request</router-link> again.</p>
                </template>
            </div>
            <div v-else>
                <div v-if="setRequestFinished" class="alert alert-success" role="alert">
                    ✊ Your password has been set <strong>successfully</strong>! The new password takes effect immediately.
                </div>
                <form v-else method="POST" class="col-md-10 mb-lg-5" @submit.prevent="onSubmit">
                    <p>Please provide a new password.</p>

                    <fieldset :disabled="setRequestIsWorking">
                        <div class="row">
                            <label for="password1" class="col-sm-3 col-form-label"><strong>New password:</strong></label>
                            <div class="col-sm-9">
                                <input id="password1" type="password" class="form-control" required="true" v-model="password1"
                                       aria-label="New password" ref="password1" minlength="8"
                                       autocomplete="new-password">
                            </div>
                        </div>
                        <div class="mb-3 row">
                            <label for="password2" class="col-sm-3 col-form-label"><strong>Repeat password:</strong></label>
                            <div class="col-sm-9">
                                <input id="password2" type="password" class="form-control" required="true"
                                       aria-label="New password again" v-model="password2"
                                       autocomplete="new-password">
                            </div>
                        </div>

                        <div class="mb-3 row">
                            <p>
                                Please read the guidelines on <a href="#faq-how-to-choose-good-pwd">How to choose a strong password?</a> below. You can only procees as soon as the following progress bar <strong>turns green</strong>.
                            </p>
                            <label for="password-quality" class="col-sm-3 col-form-label">Password quality:</label>
                            <div class="col-sm-9">
                                <password-strength :password="password1" class="mt-2"
                                                   v-on:score="qualityScore = $event"
                                                   v-on:feedback="qualityFeedback = $event"
                                                   ></password-strength>
                            </div>
                        </div>
                        <div v-if="setRequestError" class="alert alert-danger" role="alert">{{ setRequestError }}</div>

                        <div class="text-muted float-start">{{ qualityFeedback }}</div>
                        <div class="text-end" :title="setButtonTitle">
                            <button class="btn btn-outline-danger" type="submit" id="button-submit"
                                    :disabled="setButtonTitle !== null">
                                <span v-if="!setRequestIsWorking">⮷ Set password</span>
                                <span v-else>
                                    <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
                                </span>
                            </button>
                        </div>
                    </fieldset>
                </form>
            </div>
        </template>

        <h3 class="text-muted" id="faq-how-to-choose-good-pwd">How to choose a strong password?</h3>
        <p>As of today (2021) there are two approved strategies:</p>

        <ol>
            <li>Choose a <strong>reasonably complex password</strong> using <strong>multiple character classes</strong> (like uppercase, lowercase, special characters). Downside: They are hard to remember for users and potentionally lead to passwords being
                reused across different services.</li>
            <li>Choose a <strong>long password</strong> that consists of a personal sentence which is hard to break for machines and easy
                to remember for users.</li>
            <!--<li>Just for the sake of completeness: Choose a second factor to get the best possible security. This is not
                yet supported by the ECG services. But it's on our radar.</li>-->
        </ol>
        <p>If you want to create a good password you can refer to this service: <a href="https://passwordcreator.org/nl.html" target="_blank">Dutch</a> | <a href="https://passwordcreator.org/fr.html" target="_blank">French</a> | <a href="https://passwordcreator.org" target="_blank">English</a> | <a href="https://passwordcreator.org/de.html" target="_blank">German</a> | <a href="https://passwordcreator.org/es.html" target="_blank">Spanish</a>
        <p>Although currently not prevented technically it's <strong>not allowed to reuse your previous password</strong>.</p>
        <p>Furthermore we recommend using a password manager like <a href="https://keepass.info/" target="_blank">KeePass</a>.</p>
        <br />
        <h5>In case of a problem</h5>
        <p>
            You find <a href="https://wiki.ecogood.org/x/DYQjB" target="_blank"> a detailed explanation of the whole password reset process</a> in the ECG Wiki.<br />For further help just open a ticket at the <a href="https://wiki.ecogood.org/display/PUBLIC/IT-Support" target="_blank">IT support</a>.
        </p>
    </div>
</template>

<script>
    "use strict";

    import PasswordStrength from './PasswordStrength';
    import axios from 'axios';
    import zxcvbn from 'zxcvbn';

    let cssClasses = {
        0: 'bg-danger',
        1: 'bg-danger',
        2: 'bg-warning',
        3: 'bg-warning',
        4: 'bg-success'
    };

    export default {
        components: {
            PasswordStrength
        },
        data: function () {
            return {
                // step 1: validate the given token
                token: this.$route.params.token,
                validationRequestActive: true,
                validationRequestError: null,
                tokenIsValid: false,

                // step 2: set the new password
                password1: "",
                password2: "",
                setRequestIsWorking: false,
                setRequestFinished: false,
                setRequestError: null,
                qualityScore: 0,
                qualityFeedback: null,
            };
        },
        computed: {
            setButtonTitle: function () {
                if (this.qualityScore < 4) {
                    return 'The password quality is too low';
                } else if (this.password1 !== this.password2) {
                    return "The two passwords do not match";
                } else {
                    return null;
                }
            }
        },
        methods: {
            validateToken: function () {
                this.validationRequestActive = true;

                let tokenEncoded = encodeURIComponent(this.token);
                axios
                        .get(`password/token/${tokenEncoded}`)
                        .then(
                                () => this.tokenIsValid = true,
                                (error) => {
                            let containsResponse = typeof error.response !== 'undefined';
                            this.validationRequestError = containsResponse && error.response.status === 404
                                    ? null
                                    : error.message;
                        })
                        .catch(() => this.validationRequestError = "validation request error")
                        .finally(() => this.validationRequestActive = false);
            },
            onSubmit: function () {
                this.setRequestIsWorking = true;

                let tokenEncoded = encodeURIComponent(this.token);

                let config = {
                    headers: {
                        'Content-Type': 'text/plain'
                    },
                    responseType: 'text'
                };

                axios
                        .post(`password/${tokenEncoded}`, this.password1, config)
                        .then(() => {
                            this.setRequestFinished = true;
                            this.setRequestError = null;

                            localStorage.removeItem('timestamp');
                        }, (error) => {
                            let containsResponse = typeof error.response !== 'undefined';
                            this.setRequestError = containsResponse && error.response.status === 400
                                    ? "Insufficient password quality!"
                                    : error.message;
                        })
                        .finally(() => {
                            this.setRequestIsWorking = false;
                        });
            },
            onUserTest: function () {
                let uidEncoded = encodeURIComponent(this.uid);

                let config = {
                    headers: {
                        'Content-Type': 'text/plain'
                    },
                    responseType: 'text'
                };

                this.testResult = null;
                this.testIsWorking = true;

                axios
                        .post(`password/test/${uidEncoded}`, this.password, config)
                        .then((response) => {
                            this.testRequestFinished = true;
                            this.testRequestError = null;
                            this.testResult = true;
                        }, (error) => {
                            this.testResult = false;
                            this.testRequestError = error.message;
                        })
                        .finally(() => {
                            this.testIsWorking = false;
                        });
            },
            onScoreUpdate: function (score) {
                this.qualityScore = score;
            }
        },
        mounted() {
            this.validateToken();
        }
    };
</script>

<style scoped>
    #button-submit {
        min-width: 100px;
    }

    #button-submit:enabled {
        animation: pulse 0.3s 1 alternate;
    }

    @keyframes pulse {
        0% {
            transform: scale(0.95);
            box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.7);
        }

        70% {
            transform: scale(1);
            box-shadow: 0 0 0 10px rgba(0, 0, 0, 0);
        }

        100% {
            transform: scale(0.95);
            box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
        }
    }
</style>