import { Component } from '../../../lib/vues6/vues6.js'
import { auth_api } from '../../service/AuthApi.service.js'
import { location_service } from '../../service/Location.service.js'
import { message_service } from '../../service/Message.service.js'
import { password_service } from '../../service/Password.service.js'

const template = `
<div class="coreid-login-form col-lg-6 col-md-8 col-sm-10 col-xs-12 offset-lg-3 offset-md-2 offset-sm-1 offset-xs-0 text-left">
    <div class="coreid-login-form-inner">
        <div class="coreid-login-form-header font-weight-light">{{ app_name }}</div>
        <div class="coreid-login-form-message">{{ login_message }}</div>
        <form class="coreid-form" v-on:submit.prevent="do_nothing">
            <div class="form-group">
                <input
                    type="text"
                    id="coreid-login-form-username"
                    name="username"
                    class="form-control"
                    :placeholder="t['login.username']"
                    v-model="username"
                    autofocus
                    @keyup="on_key_up"
                    :disabled="loading || step_two"
                >
            </div>
            <div class="form-group" v-if="step_two">
                <input 
                    type="password" 
                    id="coreid-login-form-password" 
                    name="password" 
                    class="form-control" 
                    :placeholder="t['login.password']"
                    v-model="password"
                    :disabled="loading"
                    @keyup="on_key_up"
                    ref="password_input"
                >
            </div>
            <div v-if="error_message" class="error-message">{{ error_message }}</div>
            <div v-if="other_message" class="other-message">{{ other_message }}</div>
            <div class="buttons text-right">
                <small
                    class="mr-3"
                    v-if="!step_two && !loading && registration_enabled"
                ><a href="#" class="text-secondary" @click="on_register_click">{{ t['login.need_account'] }}</a></small>
                <small
                    class="mr-3"
                    v-if="!auth_user && !loading"
                ><a href="#" class="text-secondary" @click="on_forgot_password">{{ t['login.forgot_password'] }}</a></small>
                <button type="button" class="btn btn-primary" :disabled="loading" v-if="step_two" v-on:click="back_click">{{ t['common.back'] }}</button>  
                <button type="button" class="btn btn-primary" :disabled="loading || btn_disabled" v-on:click="step_click">{{ button_text }}</button>  
            </div>
        </form>
        <div class="coreid-loading-spinner" v-if="loading"><div class="inner"></div></div>
    </div>
</div>
`

export default class AuthLoginForm extends Component {
    static get selector() { return 'coreid-login-form' }
    static get props() { return [
        'app_name', 'login_message', 'additional_params', 'no_session', 'registration_enabled',
    ] }
    static get template() { return template }

    constructor() {
        super()

        this.username = ''
        this.password = ''
        this.button_text = ''
        this.step_two = false
        this.btn_disabled = true
        this.loading = false
        this.error_message = ''
        this.other_message = ''
        this.allow_back = true
        this.auth_user = false
        this.t = {}
    }

    watch_username(new_username, old_username) {
        this.btn_disabled = !new_username
    }

    back_click() {
        if ( !this.allow_back ) return;
        this.step_two = false
        this.button_text = this.t['common.next']
    }

    async vue_on_create() {
        const auth_user = await auth_api.get_authenticated_user()
        if ( auth_user ) {
            this.auth_user = true
            this.allow_back = false
            this.username = auth_user
            await this.step_click()
        }

        // Batch-load translations all at once to make fewer requests
        this.t = await T(
            'common.continue',
            'common.unknown_error',
            'common.cancel',
            'common.request',
            'common.back',
            'common.next',
            'login.username',
            'login.password',
            'login.need_account',
            'login.forgot_password',
            'login.username_invalid',
            'login.reset_password',
            'login.reset_password_prompt',
            'login.reset_password_success',
            'login.success',
            'login.get_started'
        )

        this.button_text = this.t['common.next']
    }

    async on_key_up(event) {
        if ( event.keyCode === 13 ) {
            // Enter was pressed
            event.preventDefault()
            event.stopPropagation()
            if ( !this.step_two && this.username ) return this.step_click(event)
            else if ( this.step_two && this.username && this.password ) return this.step_click(event)
        }
    }

    async step_click(event) {
        if ( !this.step_two ) {
            this.loading = true
            try {
                const is_valid = await auth_api.validate_username(this.username)
                if ( !is_valid ) {
                    this.error_message = this.t['login.username_invalid']
                } else {
                    this.step_two = true
                    this.button_text = this.t['common.continue']
                    this.error_message = ''
                    this.$nextTick(() => {
                        this.$refs.password_input.focus()
                    })
                }
            } catch (e) {
                this.error_message = this.t['common.unknown_error']
            }
            this.loading = false
        } else {
            this.loading = true
            this.error_message = ''

            let attempt_vars = {
                username: this.username,
                password: this.password,
                create_session: !this.no_session,
            }

            if ( typeof this.additional_params === 'object' ) {
                attempt_vars = {...attempt_vars, ...this.additional_params}
            }

            const result = await auth_api.attempt(attempt_vars)
            if ( !result.success ) {
                this.error_message = result.message || this.t['common.unknown_error']
                this.loading = false
                return
            }

            this.other_message = this.t['login.success']
            await location_service.redirect(result.next, 1500)
        }
    }

    on_register_click() {
        this.loading = true
        this.other_message = this.t['login.get_started']
        location_service.redirect('/auth/register', 1500) // TODO get this dynamically
    }

    async on_forgot_password() {
        console.log(message_service)
        await message_service.modal({
            title: this.t['login.reset_password'],
            message: this.t['login.reset_password_prompt'],
            inputs: [
                {
                    type: 'email',
                    name: 'email',
                    placeholder: 'jdoe@contoso.com',
                },
            ],
            buttons: [
                {
                    type: 'close',
                    text: this.t['common.cancel'],
                },
                {
                    type: 'close',
                    class: ['btn', 'btn-primary'],
                    text: this.t['common.request'],
                    on_click: async ($event, { email }) => {
                        await password_service.request_reset(email)
                        await message_service.alert({
                            type: 'success',
                            message: this.t['login.reset_password_success'].replace('APP_NAME', this.app_name),
                        })
                    },
                },
            ],
        })
    }

    do_nothing() {}
}
