<template lang="pug">
.form.f-col.start.mr-1.w-full(v-if="form.length")
    header
        p answers to save: {{ answers }}

    ul.w-full(v-for="(step, i) in form")
        li.f-row.start.b-solid.p-0(
            v-for="prompt in step"
            v-if="step && step.length"
            v-show="(i + 1) == state.step"
        )
            h3 {{ prompt.question }}?
            .response-wrapper(v-if="prompt.type === 'input-string'")
                label {{ prompt.type }}
                input(v-model="answers[makeKey(prompt)]")
            .response-wrapper(v-else-if="prompt.type === 'tag-cloud'")
                label {{ prompt.type }}
                button.p-0(
                    :disabled="response == answers[makeKey(prompt)]"
                    :prompt-question="makeKey(prompt)"
                    @click="respondFromTag"
                    v-for="response in prompt.responses"
                ) {{ response }}
            //- Checklist
            .response-wrapper(v-if="prompt.type === 'checklist'")
                .checklist(
                    v-for="(response, index) in prompt.responses"
                    v-bind:key="response")
                    input(
                        type="checkbox"
                        :id="response"
                        :value="response"
                        :name="response"
                        :true-value="response"
                        false-value=""
                        v-model="answers[makeKey(prompt)]")
                    label(:for="response") {{ response }}
            //- Slider from -3 to 0 to +3 (increments of 1)
            .response-wrapper(v-else-if="prompt.type === 'input-slide'")
                label {{ prompt.type }}
                input(
                    type="range"
                    min="-3"
                    max="3"
                    :prompt="makeKey(prompt)"
                    :value="answers[makeKey(prompt)]"
                    @input="setAnswer"
                )
                span {{ answers[makeKey(prompt)] }}

    footer.f-row.w-full
        button.p-1(:disabled="state.step == 1" @click="back") back
        button.p-1(:disabled="state.step == form.length" @click="next") next
        button.p-1(:disabled="state.step != form.length" @click="next") save
        .f-grow
        p step: {{ state.step }} of {{ form.length }} for {{ pid }}
</template>

<script setup>
import Joi from 'joi'
import { reactive } from 'vue'
import { useRouter } from 'vue-router'
import { validatorMapping, makeKebob } from '@/utils'
import {
    saveSurveyByProfileId,
    scoreSurveyByProfileId,
} from '../services/survey.service'
import { scoreVals } from '../../../backend/db/data-generator/config.json'

const props = defineProps({
    form: {
        type: Array,
        required: true,
    },
    pid: {
        required: true,
        type: Number,
    },
})
const makeKey = prompt => {
    return `${prompt.id}-${prompt.type}-${makeKebob(prompt.question)}`
}

/**
 * Our form is comprised of steps, and each step has a series of questions
 */
const state = reactive({ step: 1 })

/**
 * Create state object to store answers based on the questions in formSteps
 */
const answers = reactive({})

const setAnswer = e => {
    const prompt = e.target.attributes.prompt.nodeValue
    answers[prompt] = e.target.value
}
const resetAnswers = () => {
    Object.keys(answers).forEach(key => (answers[key] = null))
}
resetAnswers()
const setupAnswers = () => {
    props.form.forEach(step => {
        step.forEach(prompt => {
            answers[makeKey(prompt)] = '0'
        })
    })
}
setupAnswers()
/**
 * Callback for clicking a tag to respond
 */
const respondFromTag = e => {
    const answer = e.target.textContent
    const questionKey =
        e.target.attributes.getNamedItem('prompt-question').nodeValue
    answers[questionKey] = answer
}
/**
 * Check answered fields in current step, build a validator, then validate the answers by prompt.type
 * @param {number} step // The current step
 * @returns {object} // Joi object
 */
const isValid = step => {
    const schema = {}
    const answeredThisStep = {}
    props.form[step].forEach(prompt => {
        const key = makeKey(prompt)
        schema[key] = validatorMapping[prompt.type]
        answeredThisStep[key] = answers[key]
    })
    return Joi.object(schema).validate(answeredThisStep)
}
/**
 * Vary the final answer format by input type
 */
const formatAnswer = (inputType, answer) => {
    let formattedAnswer = answer
    if (inputType == 'slide') {
        const offset = (scoreVals.length - 1) / 2
        formattedAnswer = scoreVals[offset + parseInt(answer)].toString()
    }
    return formattedAnswer
}
/**
 * Save or take the-nNext step in the form
 */
const getInputTypeFromKey = k => {
    const inputIndex = k.split('-').indexOf('input')
    return k.split('-')[inputIndex + 1]
}

const next = async e => {
    const validity = isValid(state.step - 1)
    if (validity.error) console.error(validity.error)

    if (state.step === props.form.length) {
        // Make key map of each prompt.id
        const questiontoResponseKeyId = {}
        props.form.forEach(step => {
            step.forEach(prompt => {
                questiontoResponseKeyId[makeKey(prompt)] = prompt.id
            })
        })

        const idWithResponseVal = Object.keys(answers).map(answerKey => {
            return {
                response_key_id: questiontoResponseKeyId[answerKey],
                val: formatAnswer(
                    getInputTypeFromKey(answerKey),
                    answers[answerKey],
                ),
            }
        })

        const maxDistance = 100

        if (!props.pid) return console.error(`no pid: ${props.pid}`)

        saveSurveyByProfileId(idWithResponseVal, props.pid)
        resetAnswers()

        scoreSurveyByProfileId(props.pid, maxDistance)

        state.step = 1

        const router = useRouter()
        router.push({ name: 'HomeView' })
    } else if (state.step < props.form.length) {
        state.step++
    } else {
        console.error(
            `Cannot perform action: next() | on form step: ${state.step} of ${props.formSteps.length}`,
        )
    }
}
/**
 * Back a step in the form
 */
const back = e => {
    if (state.step > 1) {
        state.step--
    } else {
        console.error(
            `Cannot perform action: back() | on form step: ${state.step} of ${props.formSteps.length}`,
        )
    }
}
</script>

<style lang="postcss">
// prettier-ignore
@import '@/sss/theme.sss'

.form
    color: $light
    ul
        list-style: none
</style>
