<template>
	<div
			class="loader-container"
			:class="{ 'is-loading': passwordUpdateService.loading || emailUpdateService.loading || totpService.loading }">
		<div class="card">
			<header class="card-header">
				<p class="card-header-title">
					Update Your Password
				</p>
			</header>
			<div class="card-content">
				<div class="content">
					<form @submit.prevent="updatePassword()">
						<div class="field">
							<label class="label" for="newPassword">New Password</label>
							<div class="control">
								<input
										class="input"
										type="password"
										id="newPassword"
										placeholder="The new password..."
										v-model="passwordUpdate.newPassword"
										@keyup.enter="updatePassword"/>
							</div>
						</div>
						<div class="field">
							<label class="label" for="newPasswordConfirm">New Password Confirmation</label>
							<div class="control">
								<input
										class="input"
										type="password"
										id="newPasswordConfirm"
										placeholder="Confirm your new password..."
										v-model="passwordConfirm"
										@keyup.enter="updatePassword"/>
							</div>
						</div>
						<div class="field">
							<label class="label" for="currentPassword">Current Password</label>
							<div class="control">
								<input
										class="input"
										type="password"
										id="currentPassword"
										placeholder="Your current password"
										v-model="passwordUpdate.oldPassword"
										@keyup.enter="updatePassword"/>
							</div>
						</div>
					</form>

					<div class="bigbuttons">
						<button @click="updatePassword()" class="button is-primary is-fullwidth"
								:class="{ 'is-loading': passwordUpdateService.loading}">
							Save
						</button>
					</div>
				</div>
			</div>
		</div>
		<div class="card">
			<header class="card-header">
				<p class="card-header-title">
					Update Your E-Mail Address
				</p>
			</header>
			<div class="card-content">
				<div class="content">
					<form @submit.prevent="updateEmail()">
						<div class="field">
							<label class="label" for="newEmail">New Email Address</label>
							<div class="control">
								<input
										class="input"
										type="email"
										id="newEmail"
										placeholder="The new email address..."
										v-model="emailUpdate.newEmail"
										@keyup.enter="updateEmail"/>
							</div>
						</div>
						<div class="field">
							<label class="label" for="currentPassword">Current Password</label>
							<div class="control">
								<input
										class="input"
										type="password"
										id="currentPassword"
										placeholder="Your current password"
										v-model="emailUpdate.password"
										@keyup.enter="updateEmail"/>
							</div>
						</div>
					</form>

					<div class="bigbuttons">
						<button @click="updateEmail()" class="button is-primary is-fullwidth"
								:class="{ 'is-loading': emailUpdateService.loading}">
							Save
						</button>
					</div>
				</div>
			</div>
		</div>
		<div class="card" v-if="totpEnabled">
			<header class="card-header">
				<p class="card-header-title">
					Two Factor Authentication
				</p>
			</header>
			<div class="card-content">
				<a
						class="button is-primary"
						v-if="!totpEnrolled && totp.secret === ''"
						@click="totpEnroll()"
						:class="{ 'is-loading': totpService.loading }">
					Enroll
				</a>
				<div class="content" v-else-if="totp.secret !== '' && !totp.enabled">
					<p>
						To finish your setup, use this secret in your totp app (Google Authenticator or similar):
						<strong>{{ totp.secret }}</strong><br/>
						After that, enter a code from your app below.
					</p>
					<p>
						Alternatively you can scan this QR code:<br/>
						<img :src="totpQR" alt=""/>
					</p>
					<div class="field">
						<label class="label" for="totpConfirmPasscode">Passcode</label>
						<div class="control">
							<input
									class="input"
									type="text"
									id="totpConfirmPasscode"
									placeholder="A code generated by your totp application"
									v-model="totpConfirmPasscode"
									@keyup.enter="totpConfirm()"/>
						</div>
					</div>
					<a class="button is-primary" @click="totpConfirm()">Confirm</a>
				</div>
				<div class="content" v-else-if="totp.secret !== '' && totp.enabled">
					<p>
						You've sucessfully set up two factor authentication!
					</p>
					<p v-if="!totpDisableForm">
						<a class="button is-danger" @click="totpDisableForm = true">Disable</a>
					</p>
					<div v-if="totpDisableForm">
						<div class="field">
							<label class="label" for="currentPassword">Please Enter Your Password</label>
							<div class="control">
								<input
										class="input"
										type="password"
										id="currentPassword"
										placeholder="Your current password"
										v-model="totpDisablePassword"
										@keyup.enter="totpDisable"
										v-focus/>
							</div>
						</div>
						<a class="button is-danger" @click="totpDisable()">Disable two factor authentication</a>
					</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script>
	import PasswordUpdateModel from '../../models/passwordUpdate'
	import PasswordUpdateService from '../../services/passwordUpdateService'
	import EmailUpdateService from '../../services/emailUpdate'
	import EmailUpdateModel from '../../models/emailUpdate'
	import TotpModel from '../../models/totp'
	import TotpService from '../../services/totp'

	import {mapState} from 'vuex'

	export default {
		name: 'Settings',
		data() {
			return {
				passwordUpdateService: PasswordUpdateService,
				passwordUpdate: PasswordUpdateModel,
				passwordConfirm: '',

				emailUpdateService: EmailUpdateService,
				emailUpdate: EmailUpdateModel,

				totpService: TotpService,
				totp: TotpModel,
				totpQR: '',
				totpEnrolled: false,
				totpConfirmPasscode: '',
				totpDisableForm: false,
				totpDisablePassword: '',
			}
		},
		created() {
			this.passwordUpdateService = new PasswordUpdateService()
			this.passwordUpdate = new PasswordUpdateModel()

			this.emailUpdateService = new EmailUpdateService()
			this.emailUpdate = new EmailUpdateModel()

			this.totpService = new TotpService()
			this.totp = new TotpModel()

			this.totpStatus()
		},
		computed: mapState({
			totpEnabled: state => state.config.totpEnabled
		}),
		methods: {
			updatePassword() {
				if (this.passwordConfirm !== this.passwordUpdate.newPassword) {
					this.error({message: 'The new password and its confirmation don\'t match.'}, this)
					return
				}

				this.passwordUpdateService.update(this.passwordUpdate)
					.then(() => {
						this.success({message: 'The password was successfully updated.'}, this)
					})
					.catch(e => this.error(e, this))
			},
			updateEmail() {
				this.emailUpdateService.update(this.emailUpdate)
					.then(() => {
						this.success({message: 'Your email address was successfully updated. We\'ve sent you a link to confirm it.'}, this)
					})
					.catch(e => this.error(e, this))
			},
			totpStatus() {
				if (!this.totpEnabled) {
					return
				}
				this.totpService.get()
					.then(r => {
						this.$set(this, 'totp', r)
						this.totpSetQrCode()
					})
					.catch(e => {
						// Error code 1016 means totp is not enabled, we don't need an error in that case.
						if (e.response && e.response.data && e.response.data.code && e.response.data.code === 1016) {
							this.totpEnrolled = false
							return
						}

						this.error(e, this)
					})
			},
			totpSetQrCode() {
				this.totpService.qrcode()
					.then(qr => {
						const urlCreator = window.URL || window.webkitURL
						this.totpQR = urlCreator.createObjectURL(qr)
					})
			},
			totpEnroll() {
				this.totpService.enroll()
					.then(r => {
						this.totpEnrolled = true
						this.$set(this, 'totp', r)
						this.totpSetQrCode()
					})
					.catch(e => this.error(e, this))
			},
			totpConfirm() {
				this.totpService.enable({passcode: this.totpConfirmPasscode})
					.then(() => {
						this.$set(this.totp, 'enabled', true)
						this.success({message: 'You\'ve successfully confirmed your totp setup and can use it from now on!'}, this)
					})
					.catch(e => this.error(e, this))
			},
			totpDisable() {
				this.totpService.disable({password: this.totpDisablePassword})
					.then(() => {
						this.totpEnrolled = false
						this.$set(this, 'totp', new TotpModel())
						this.success({message: 'Two factor authentication was sucessfully disabled.'}, this)
					})
					.catch(e => this.error(e, this))
			},
		},
	}
</script>
