<template>
<div class="panel">

<template v-if="user">
<side-bar v-if="user"
:role="user && user.status"
:avatar="user.avatar"
:active="active">
</side-bar>

<div v-if="loading" class="page loading">
<span class="error" >{{loadingError}}</span>
<spinner></spinner>
</div>

<home :user="user" v-else-if="active == 1" />
<new-estimate
:user="user"
:fees="fees"
:token="token"
v-else-if="active == 2" />

<estimates
:user="user"
:fees="fees"
v-else-if="active == 3"
:token="token" 
@addFeeTemp="(f) => fees.push(f)"
@removeFeeTemp="(fee) => fees = fees.filter(f => f.id != fee.id)"
@preview="previewEstimate"
/>

<settings
:user="user"
:token="token"
@updateAvatar="updateAvatar"
@updateLetterhead="updateLetterhead"
v-else-if="active == 4" />

<sign-out :user="user" v-else-if="active == 5" />

</template>

<template v-if="!user && active == 6">
<login @login="start" />
</template>

<estimate-test
v-else-if="active == 7"
:token="token"
:estimate="preview"
/>

</div>
</template>

<script>
import SideBar from "./sidebar.vue"
import Spinner from "./spinner.vue"
import Home from "./home.vue"
import NewEstimate from "./new/new.vue"
import Estimates from "./estimates.vue"
import EstimateTest from "./estimate-test.vue"
import Settings from "./settings.vue"
import SignOut from "./sign-out.vue"
import Login from "./login.vue"

function getCookie(name) {
	var re = new RegExp(name + "=([^;]+)")
	var value = re.exec(document.cookie)

	return (value != null) ? unescape(value[1]) : null
}

function refreshToken() {
	const token = getCookie("skouter")
	const timeout = setTimeout(this.refreshToken, 1000*60*25)

	fetch(`/api/token`,
		{method: 'GET',
		headers: {
			"Accept": "application/json",
			"Authorization": `Bearer ${token}`,
			},
	}).then(response => {
		if (!response.ok) {
			console.log("Error refreshing token.")
			clearTimeout(timeout)
			window.location.hash = '#login'
		} else {
		    this.token = getCookie("skouter")
		}
	})
}

function getUser() {
	const token = getCookie("skouter")
	this.token = token

	return fetch(`/api/user`,
		{method: 'GET',
		headers: {
			"Accept": "application/json",
			"Authorization": `Bearer ${token}`,
    		},
	}).then(response => {
		if (response.ok) {
			return response.json()
		} else {
			// Redirect to login if starting token is invalid
			window.location.hash = '#login'
		}
	}).then (result => {
		if (!result || !result.length) return // Exit if token is invalid
		this.user = result[0]
		if (this.user.avatar) return
		
		return getAvatar(token)
	}).then(b => {
	    const validTypes = ['image/jpeg', 'image/png']
    
        if (!validTypes.includes(b.type) || b.size <= 1) {
            fetch("/assets/image/empty-avatar.jpg").
            then(r => r.blob()).then( a => this.user.avatar = a )
            return
        }
        
        this.user.avatar = b
        return getLetterhead(token)
	}).then(b => {
	    const validTypes = ['image/jpeg', 'image/png']
    
        if (!validTypes.includes(b.type) || b.size <= 1) {
            fetch("/assets/image/empty-letterhead.jpg").
            then(r => r.blob()).then( a => this.user.letterhead = a )
            return
        }
        
        this.user.letterhead = b
	})

}

function getAvatar(t) {
    return fetch("/api/user/avatar",
        {method: 'GET',
            headers: {
            "Accept": "application/json",
            "Authorization": `Bearer ${t || this.token}`,
            }
        }).then(r => r.blob())
}

function getLetterhead(t) {
    return fetch("/api/user/letterhead",
        {method: 'GET',
            headers: {
            "Accept": "application/json",
            "Authorization": `Bearer ${t || this.token}`,
            }
        }).then(r => r.blob())
}

function updateAvatar() {
	const token = getCookie("skouter")
    getAvatar(token).then(b => this.user.avatar = b)
}

function updateLetterhead() {
	const token = getCookie("skouter")
    getLetterhead(token).then(b => this.user.letterhead = b)
}

function getFees() {
	const token = getCookie("skouter")
	
	return fetch(`/api/fees`,
		{method: 'GET',
    		headers: {
        	"Accept": "application/json",
        	"Authorization": `Bearer ${token}`,
    		},
	}).then(response => {
		if (response.ok) { return response.json() }
	}).then (result => {
		if (!result || !result.length) return // Exit if token is invalid or no fees are saved
		this.fees = result
	})

}

// Used to check the current section of the app generally without a regex match
// each time.
function active() {
	if (this.hash == '' || this.hash == '#') {
		return 1
	} else if (/^#new\/?/.exec(this.hash)) {
		return 2
	} else if (/^#estimates\/?/.exec(this.hash)) {
		return 3
	} else if (/^#settings\/?/.exec(this.hash)) {
		return 4
	} else if (/^#sign-out\/?/.exec(this.hash)) {
		return 5
	} else if (/^#login\/?/.exec(this.hash)) {
		return 6
	} else if (/^#estimate\/?/.exec(this.hash)) {
		return 7
	} else {
		return 0
	}
}

// Fetch data before showing UI. If requests fail, assume token is expired.
function start() {
	this.loading = true

	let loaders = []
	loaders.push(this.getUser())
	loaders.push(this.getFees())
	Promise.all(loaders).then((a, b) => {
		this.loading = false
		if (!b) {
			// Time untill token expiration may have elapsed before the page
			// reloaded
			this.refreshToken()
		}
	}).catch(error => {
		console.log("An error occured %O", error)
		this.loadingError = "Could not initialize app."
		window.location.hash = 'login'
	})

}

function previewEstimate(estimate) {
    this.preview = estimate
    window.location.hash = 'estimate'
}

export default {
	components: {
		SideBar,
		Spinner,
		Home,
		NewEstimate,
		EstimateTest,
		Estimates,
		Settings,
		SignOut,
		Login
	},
	computed: { active },
	methods: {
		getCookie,
		start,
		getUser,
		getFees,
		refreshToken,
		updateAvatar,
		getAvatar,
		updateLetterhead,
		getLetterhead,
		previewEstimate,
	},
	data() {
		return {
			loading: true,
			user: null,
			hash: window.location.hash,
			fees: [],
			loadingError: "",
			token: '',
			preview: null,
		}
	},
	created() {
		window.onhashchange = () => this.hash = window.location.hash
		this.token = this.getCookie("skouter")

		if (!this.token) {
			window.location.hash = 'login'
			this.loading = false
			return
		}
		this.start()
	}
}
</script>