<template>
    <div class="main d-flex w-100">
        <div class="container d-flex flex-column">
            <div class="row vh-100">
                <div class="col-sm-10 col-md-8 col-lg-6 mx-auto d-table h-100">
                    <div class="d-table-cell align-middle">
                        <div class="text-center mt-4">
                            <h1 class="h2">
                                Toolshed
                            </h1>

                            <p class="lead" v-if="msg">
                                {{ msg }}
                            </p>
                            <p class="lead" v-else>
                                Create an account to get started
                            </p>
                        </div>
                        <div class="card">
                            <div class="card-body">
                                <div class="m-sm-4">
                                    <div :class="errors.raw_record?['mb-3','is-invalid']:['mb-3']">
                                        <label class="form-label">Identity Record</label>
                                        <div class="input-group">
                                            <input class="form-control form-control-lg" type="text"
                                                   :class="errors.raw_record?['is-invalid']:[]"
                                                   v-model="raw_record" placeholder="Paste identity record"
                                                   @input.prevent="try_parsing">
                                            <span class="input-group-text  form-control-lg" v-if="raw_record == ''"
                                                  @click="pasteClipboard()">
                                                    <b-icon-clipboard></b-icon-clipboard>
                                                </span>
                                            <span class="input-group-text  form-control-lg" v-else
                                                  @click="raw_record = ''">
                                                    <b-icon-x-circle></b-icon-x-circle>
                                                </span>
                                        </div>
                                        <div class="invalid-feedback">
                                            {{ errors.raw_record }}
                                        </div>
                                    </div>

                                    <div class="mb-3" v-if="is_unlocked || is_locked">
                                        <label class="form-label">Username</label>
                                        <div class="input-group">
                                            <input class="form-control form-control-lg" type="email"
                                                   disabled v-model="username">
                                            <span class="input-group-text form-control-lg bg-success"
                                                  v-if="is_unlocked">
                                                    <b-icon-unlock></b-icon-unlock>
                                                </span>
                                            <span class="input-group-text  form-control-lg bg-warning"
                                                  v-if="is_locked">
                                                    <b-icon-lock></b-icon-lock>
                                                </span>
                                        </div>
                                    </div>

                                    <div class="mb-3" v-if="is_locked" :class="errors.password?['is-invalid']:[]">
                                        <form role="form" method="post" @submit.prevent="try_unlock">
                                            <label class="form-label">Password</label>
                                            <div class="input-group">
                                                <input class="form-control form-control-lg" type="password"
                                                       name="password" placeholder="Enter your password"
                                                       v-model="password" :class="errors.password?['is-invalid']:[]">
                                                <button class="btn btn-lg btn-primary" type="button"
                                                        @click="try_unlock">
                                                    <b-icon-unlock></b-icon-unlock>
                                                    unlock
                                                </button>
                                            </div>
                                            <div class="invalid-feedback">
                                                {{ errors.password }}
                                            </div>

                                        </form>
                                    </div>

                                    <div>
                                        <label class="form-check">
                                            <input class="form-check-input" type="checkbox" value="remember-me"
                                                   name="remember-me" checked v-model="remember"
                                                   @change="setRemember(remember)">
                                            <span class="form-check-label">
												Remember me next time
												</span>
                                        </label>
                                    </div>

                                    <div class="text-center mt-3">
                                        <button type="submit" class="btn btn-lg btn-primary" :disabled="!is_unlocked"
                                                @click="try_pairing">
                                            Pair
                                        </button>
                                    </div>
                                    <br/>
                                    <div class="text-center">
                                        <p class="mb-0 text-muted">
                                            Already have an account?
                                            <router-link to="/login">Login</router-link>
                                        </p>
                                        <p class="mb-0 text-muted">
                                            Don’t have an account?
                                            <router-link to="/register">Sign up</router-link>
                                        </p>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import {mapActions, mapMutations} from 'vuex';
import {ServerSet, createSignAuth} from '../federation';
import NeighborsCache from '../neigbors';
import {decryptIdentityRecord, parseIdentityRecord, serializeIdentityRecord} from "@/identity";
import router from "@/router";

export default {
    name: 'Pairing',
    data() {
        return {
            msg: 'Pair with existing Account',
            //raw_record: 'test_a@a.localhost:4ab79601edc400fd0263c7d5fd045ea7f5de28f1dd8905e2479f96893f3257d8:7f0ee42b',
            //raw_record: 'test_a@a.localhost:$pbkdf2$100000$67da1c2a055dd41fc9707c37d2cdecea$8173b4d626352bcafab626b2$60027066142f55ecfd6f91b587f99c5f02ee536ce08c31e3f69148a51711489220a2b10d5450166ee09a781f891be8ab3a418e31a8e71f6468f189ba0baf31ece21166b63ba608683bdbea8afa7dfc33b1a994d8be4e4b2123',
            raw_record: '',
            crypted_record: null,
            username: '',
            password: '',
            keypair: '',
            remember: false,
            errors: {}
        }
    },
    computed: {
        is_unlocked() {
            return !!this.keypair && !!this.username;
        },
        is_locked() {
            return !!this.username && !!this.crypted_record && !this.keypair;
        }
    },
    methods: {
        ...mapActions(['lookupServer']),
        ...mapMutations(['setRemember', 'setUserFromIdentityRecord']),
        async try_pairing() {
            const unreachable = new NeighborsCache();
            const servers = await this.lookupServer({username: this.username}).then(servers => new ServerSet(servers, unreachable))
            const auth = createSignAuth(this.username, this.keypair.signSk);
            const reply = await servers.getRaw(auth, '/api/friends/');
            if (reply.status === 200) {
                this.setUserFromIdentityRecord({username: this.username, keypair: this.keypair});
                router.push({path: '/'});
            } else {
                console.error('Error:', reply);
            }
        },
        try_parsing() {
            if (!this.raw_record) {
                this.username = '';
                this.keypair = '';
                this.errors = {};
                return;
            }
            const parsed = parseIdentityRecord(this.raw_record)
            const {user, keypair, errors} = parsed;
            if (user) {
                this.username = user;
            }
            if (errors) {
                this.errors.raw_record = errors;
            }
            if (keypair) {
                this.keypair = keypair;
            }
            if (parsed.crypted) {
                this.crypted_record = parsed;
            }
        },
        async try_unlock() {
            const {
                user,
                keypair,
                errors
            } = await decryptIdentityRecord(this.crypted_record, this.username, this.password);
            if (user) {
                this.username = user;
            }
            if (errors) {
                this.errors.password = errors;
            }
            if (keypair) {
                this.keypair = keypair;
            }
        },
        async pasteClipboard() {
            try {
                this.raw_record = await navigator.clipboard.readText();
                this.try_parsing()
            } catch (e) {
                console.error('Error:', e);
            }
        }
    },
    mounted() {
        try {
            fetch('/local/domains')
                .then(response => response.json())
                .then(data => {
                    this.domains = data;
                });
        } catch (e) {
            console.error('Error:', e);
        }
    }
}
</script>

<style scoped>
.is-invalid input, .is-invalid select {
    border: 1px solid var(--bs-danger);
}

.is-invalid .invalid-feedback {
    display: block;
}

.input-group-text svg {
    overflow: visible;
}
</style>