<template lang="pug">
main.view--survey.f-col.start.w-full
    header.w-full.f-col
        p survey for profile: {{ current }}
    article.match.w-full
        ul.w-full
            template(v-for="(q, i) in profileQuestions" :key="q.response_key_prompt")
                li(v-if="step == i + 1")
                    p {{q.response_key_category}}: 
                        span in db:
                        span(v-if="q.response_key_id") true - id:{{q.response_key_id}} | 
                        span(v-else) false | 
                        span {{q.response_key_prompt}}? 
                        span {{q.response_key_description}} 

                        //- Select
                        div(v-if="q.responses.length")
                            button(
                                v-for="(res, index) in q.responses"
                                :key="index"
                                @click="storeResponseLike(step, q.response_key_id, q.response_key_prompt, res); step++"
                            ).p-0 {{res}}
                        
                        //- Fill in the blank
                        div(v-else-if="q.response_key_category === 'profile'")
                            input(@input="storeResponseLike(step, q.response_key_id, q.response_key_prompt, profile[q.response_key_prompt])" v-model="profile[q.response_key_prompt]" @keyup.enter="step++") 
                            label >{{ profile[q.response_key_prompt]}}
                        
                        //- Aspects
                        div(v-else).f-col
                            input(type="range" min="-3" max="3" list="ticks" @input="storeResponseLike(step, q.response_key_id, q.response_key_prompt, aspects[q.response_key_category])" v-model="aspects[q.response_key_category]").w-full
                            label {{ aspectResponses[parseInt(aspects[q.response_key_category]) + 3] }} 
                    
                        nav.f-row
                            button(:disabled="step == 0" @click="step--") back
                            p {{step}} of {{profile.length}}
                            button(
                                v-if="(q.response_key_category === 'profile')"
                                @click="storeResponseLike(step, q.response_key_id, q.response_key_prompt, profile[q.response_key_prompt]); step++"
                            ) next
                            button(
                                v-else
                                @click="storeResponseLike(step, q.response_key_id, q.response_key_prompt, aspects[q.response_key_category]); step++"
                            ) next
                    
            //- Confirmation
            li(v-if="step == profileQuestions.length + 1")
                p Does this look correct?
                h4 {{ profile }}
                h4 {{aspects}}
                nav.f-row
                    button(@click="step--") back
                    p(@click="step = 1").p-1 start over
                    button(@click="onSave") save
                    //- button(@click="$router.push({ name: 'HomeView' })") save
    footer
        button(@click="bypass") +30 user profiles
</template>

<script>
import { surveyFactory, randomSurveyResponses } from '@/utils'
import { allSteps, aspectResponses, possible } from '@/utils/lang'

import { currentProfile, createProfileForUserId, fetchProfileByProfileId, scoreSurveyByProfileId, signupUser } from '@/services'

import { maxDistanceKey } from '../../../backend/db/data-generator/config.json'

export default {
    props: {
        pid: {
            type: Number,
        },
    },
    data() {
        return {
            bypassCount: 0,
            validSurvey: null,
            step: 1,
            responseLikes: {},
            profile: {},
            aspects: {
                grit: 0,
                openness: 0,
                bravery: 0,
                empathy: 0,
                honesty: 0,
                respect: 0,
            },
            aspectResponses: Object.values(aspectResponses.usa)
        }
    },
    computed: {
        current() {
            return currentProfile
        },
        profileQuestions() {
            if (!this.validSurvey) return []
            return this.validSurvey.steps
        },
    },
    async created() {
        /**
         * Before this ever gets called, surveyFactory.questionsFromDb
         * must be set by App.created()
         */
        this.validSurvey = await surveyFactory.createSurvey(
            allSteps['usa'],
            possible['usa']['roles'],
        )
    },
    methods: {
        // Just for testing quicker
        bypass() {
            const n = 30
            const toGen = [...Array(n).keys()]
            toGen.forEach(async () => {
                const randRes = randomSurveyResponses(this.bypassCount)
                randRes.forEach((tr, i) => {
                    this.storeResponseLike(i, tr.idOrPrompt, tr.idOrPrompt, tr.val)
                })
                this.bypassCount++
                await this.onSave()
            })
            this.step = 21
            console.warn(`Auto-filling survey ${n} times...`)
        },
        storeResponseLike(step, id, prompt, val) {
            // Also update the form model state for now
            // We probably can refactor this out
            this.profile[prompt] = val
            
            /**
             * If NO response id is present, that means the answer
             * is required and associated with a User and NOT a Profile
             **/
            this.responseLikes[`step-${step}`] = {
                idOrPrompt: id ? id : prompt,
                val: val.toString()
            }
        },
        _formatIntoResponses(survey) {
            return survey.map(resLike => {
                resLike.response_key_id = resLike.idOrPrompt
                delete resLike.idOrPrompt
                return resLike
            })
        },
        /**
         * Survey responses have User information
         * mixed in with scoring information so we 
         * need to separate them
         * @param {array} responseLikes answered by the survey
         */
        _separateUserInfoFromResponses(responseLikes) {
            let survey = []
            const user = {}
            responseLikes.forEach(resLike => {
                if(resLike.idOrPrompt && Number.isFinite(parseInt(resLike.idOrPrompt))) {
                    survey.push(resLike)
                } else {
                    user[resLike.idOrPrompt] = resLike.val
                }
            })
            return [user, this._formatIntoResponses(survey)]
        },
        async _createUserProfileRel(user, survey) {
            /** A User is required before creating a profile */
            const createdUser = await signupUser(user)
            if(!createdUser) return

            const userProfileRel = await createProfileForUserId(createdUser.user_id, survey)
            if(!userProfileRel) return 

            return userProfileRel
        },
        async _getProfileWithScore(createdProfileId, maxDistance) {
            /** A Profile is associated with n:1 user and referenced by profile id */
            const fetchedProfile = await fetchProfileByProfileId(createdProfileId)
            if(!fetchedProfile) {
                console.error(`Could not fetch Profile ${createdProfileId}. Please check that a User and Profile were created.`)
                return
            }

            /** Use profile answers to compare against other profile answers */
            const scored = await scoreSurveyByProfileId(createdProfileId, maxDistance)
            if(!scored) {
                console.error(`Could not score Profile ${createdProfileId}.`)
                return
            }
            return fetchedProfile
        },
        async _setLoginForProfile(profile) {
            const currentId = currentProfile.login(profile.profile_id)
            if(currentId && profile.responses.length) {
                // Stores responses without fetching again
                currentProfile.setResponses(profile.responses)
            }
            if(!currentProfile.isComplete) {
                console.error(`Profile ${currentProfile.id} is incomplete. Please make sure all survey questions have been answered.`)
                return
            }
        },
        async onSave() {
            const [ user, survey] = this._separateUserInfoFromResponses(Object.values(this.responseLikes))
            const maxDistanceRes = survey.find(res => res.response_key_id == maxDistanceKey)

            /**
             * Creating a profile only returns the created
             * user id and profile id
             **/
            const userProfileRel = await this._createUserProfileRel(user, survey)
            const createdProfileId = userProfileRel.profile_id

            /** A Profile is associated with n:1 user and referenced by profile id */
            const fetchedProfile = await this._getProfileWithScore(createdProfileId, maxDistanceRes.val)
            
            /** 
             * Login only after there is a user and
             * that user has a profile and all responses
            */
            this._setLoginForProfile(fetchedProfile)
            
            this.$router.push({ name: 'HomeView' })
        },
        back(prompt) {
            this[prompt] = ''
            this.step--
        },
    },
}
</script>

<style lang="postcss">
.slide-up
    &-leave, &-enter
        &-active
            transition-delay: 500ms
            transition-property: opacity, background-color, font-size, transform, color
            transition-timing-function: cubic-bezier(1, 0.3, 0.5, 1)
            transition-duration: 300ms
    &-enter-from, &-leave-to
        opacity: 0

.fade
    animation: fadeIn 1200ms ease-in

@keyframes fadeIn
    0%
        opacity: 0
    50%
        opacity: 0.5
    100%
        opacity:1

h1
    color: white

main
    padding: 5vh
    display: flex
    header
        p
            color: #666
            line-height: 1.3em
        color: #ccc
        font-style: italic
        text-align: left

article
    height: 100%
    width: 100%
    flex-direction: column
    ul
        height: 100%
        list-style: none
        button
            padding: 1em
        p
            padding: 1em
            color: white
.form
    border: 1px solid #fff
    width: 100%
    header, footer, ul
        padding: 1vh
    ul
        display: flex
        width: 100%
        > li
            flex-direction: column
            border: 0px solid yellow
            width: 100%
            padding: 0
            text-align: left
            label
                margin-right: 1vh
            > h3
                text-transform: capitalize
                padding: 1vh 0
            > div > span
                display: block
                text-align: center
</style>
