<template>

    <div
            class="questionWrap"
            :class="validationClass"
            v-if="question.visible"
            :id="'question_wrap_' + question.id"
    >

        <div class="row">

            <div class="questionNumberCol" v-if="questionNumber">
                <div class="questionNumber">
                    <span v-html="questionNumber"></span>
                </div>
            </div> <!-- .questionNumberCol -->

            <label
                    :for="'question_' + question.id"
                    v-html="question.question_text"
                    class="questionText"
            ></label>

            <div class="formError" v-if="hasError">
                <p v-html="errorMessage"></p>
            </div> <!-- .tester -->

            <div class="inputWrap">

                <yes-no
                        v-if="matchType('yes_no')"
                        :question="question"
                        @update-question="updateQuestion"
                        ref="yesNo"
                />

                <variations
                        v-else-if="matchType('variations')"
                        :question="question"
                        @update-question="updateQuestion"
                        ref="variations"
                />

                <confirmation
                        v-else-if="matchType('confirmation')"
                        :question="question"
                        @update-question="updateQuestion"
                        ref="confirmation"
                />

                <date-field
                        v-else-if="matchType('date')"
                        :question="question"
                        @update-question="updateQuestion"
                        ref="dateField"
                />

                <number-field
                        v-else-if="matchType('number')"
                        :question="question"
                        :allow-input-event="changed"
                        @update-question="updateQuestion"
                        ref="number"
                />

                <email-field
                        v-else-if="matchType('email')"
                        :question="question"
                        placeholder="example@website.com"
                        :allow-input-event="changed"
                        @update-question="updateQuestion"
                        ref="email"
                />

                <image-upload
                        v-else-if="matchType('image')"
                        :question="question"
                        @update-question="updateQuestion"
                        ref="image"
                />

                <tag-input
                        v-else-if="matchType('allergies')"
                        :question="question"
                        :default-tags="$store.state.user.healthProfile.allergies"
                        placeholder="Add allergy"
                        :autocomplete-items="[]"
                        @update-question="updateQuestion"
                        ref="tagInput"
                />

                <tag-input
                        v-else-if="matchType('medications')"
                        :question="question"
                        :default-tags="$store.state.user.healthProfile.medications"
                        placeholder="Add medication"
                        :autocomplete-items="$store.state.medicationsList"
                        @update-question="updateQuestion"
                        ref="tagInput"
                />

                <tag-input
                        v-else-if="matchType('conditions')"
                        :question="question"
                        :default-tags="$store.state.user.healthProfile.conditions"
                        placeholder="Add condition"
                        :autocomplete-items="$store.state.medicalConditionList"
                        @update-question="updateQuestion"
                        ref="tagInput"
                />

                <textarea-field
                        v-else-if="matchType('textarea')"
                        :question="question"
                        placeholder=""
                        :allow-input-event="changed"
                        @update-question="updateQuestion"
                        ref="text"
                />

                <notify-gp
                        v-else-if="matchType('notify_gp')"
                        :question="question"
                        @update-question="updateQuestion"
                        ref="notifyGP"
                />

                <bmi-calculator
                        v-else-if="matchType('bmi')"
                        :question="question"
                        :set-type="question.bmi_field_values.type"
                        :set-height-cm="question.bmi_field_values.height_cm"
                        :set-weight-kg="question.bmi_field_values.weight_kg"
                        :set-height-feet="question.bmi_field_values.height_feet"
                        :set-height-inches="question.bmi_field_values.height_inches"
                        :set-weight-stone="question.bmi_field_values.weight_stone"
                        :set-weight-pounds="question.bmi_field_values.weight_pounds"
                        :set-ethnicity-id="question.bmi_field_values.ethnicity_id"
                        @update-question="updateQuestion"
                        ref="bmi"
                />

                <weight-field
                        v-else-if="matchType('weight')"
                        :question="question"
                        :set-type="question.weight_field_values.type"
                        :set-weight-kg="question.weight_field_values.weight_kg"
                        :set-weight-stone="question.weight_field_values.weight_stone"
                        :set-weight-pounds="question.weight_field_values.weight_pounds"
                        @update-question="updateQuestion"
                        ref="weight"
                />

                <bp-field
                        v-else-if="matchType('bp_readings')"
                        :question="question"
                        @update-question="updateQuestion"
                        ref="bp_readings"
                />

                <input type="hidden"
                       :name="'change_count[' + question.id + ']'"
                       v-model="question.answer_change_count"
                />

            </div> <!-- .inputWrap -->

        </div> <!-- .row -->

    </div> <!-- .questionWrap -->

</template>

<script>


import { isUndefined, isEmpty } from 'lodash';
import yesNo from '../fields/yes_no';
import variations from '../fields/variations';
import confirmation from '../fields/confirmation';
import dateField from '../fields/date_field';
import numberField from '../fields/number_field';
import weightField from '../fields/weight_field';
import bpField from '../fields/bp_field';
import emailField from '../fields/email_field';
import imageUpload from '../fields/image_upload';
import tagInput from '../fields/tag_input';
import textareaField from '../fields/textarea_field';
import notifyGp from '../fields/notify_gp';
import bmiCalculator from '../fields/bmi_calculator';

export default {
    name: 'questionWrap',
    components: {
        yesNo,
        variations,
        confirmation,
        dateField,
        numberField,
        weightField,
        bpField,
        emailField,
        imageUpload,
        tagInput,
        textareaField,
        notifyGp,
        bmiCalculator,
    },
    props: {
        questionNumber: {
            type: [Number, String],
            default (rawProps) {
                return 0;
            }
        },
        questionId: {
            type: [Number, String],
            default (rawProps) {
                return 0;
            }
        },
    },
    data() {
        return {
            changed: false,
            defaultErrorMessages: {
                email: 'To continue, please enter a valid email address',
                yes_no: 'To continue, please select an option',
                textarea: 'To continue, please fill out this text box',
                number: 'To continue, please enter a number',
                weight: 'To continue, please enter a number',
                conditions: 'To continue, please enter your conditions into the box provided',
                medications: 'To continue, please enter your current medications into the box provided',
                allergies: 'To continue, please enter any allergies you have in the box provided',
                notify_gp: 'To continue, please search and add your GP\s address or enter it manually',
                image: 'To continue, please upload an image',
                variations: 'To continue, please select an option',
                confirmation: 'To continue, please select an option from below',
                bmi: 'To continue, please enter your height and weight',
                date: 'To continue, please select a valid date',
            }
        }
    },

    computed: {

        hasError() {
            return this.question.has_error || (this.question.question_type == 'image' && this.question?.file_error?.length);
        },

        errorMessage() {

            let error = this.defaultErrorMessages[this.question.question_type];

            if(this.question.question_type == 'image') {

                if(this.question?.file_error?.length) {
                    error = this.question.file_error;
                }

            }else if(!isUndefined(this.question.error_message)) {

                if(this.question.error_message.length) {
                    error = this.question.error_message;
                }
            }

            return error;

        },

        question() {

            return this.getQuestion();

        },

        validationClass() {

            let question = this.getQuestion();

            let cssClass = [];

            if(question.has_error) {
                cssClass.push('hasError');
            }else if(question.can_proceed && this.changed) {
                cssClass.push('isValid');
            }

            return cssClass;
        }

    },
    methods: {

        getQuestion() {

            return this.getQuestionByKey('id', this.questionId);

        },

        matchType(type) {

            let question = this.getQuestion();

            if(!isUndefined(question.question_type)) {
                return question.question_type == type;
            }else{
                return false;
            }
        },

        updateQuestion(question) {

            this.changed = true;

            question = this.setErrors(question);

            question.answer_change_count++;

            this.$store.dispatch('updateAssessmentQuestion', question);

            this.updateVisibility(question);

        },

        setErrors(question) {

            if(question.can_proceed) {
                question.has_error = false;
            }else{
                question.has_error = true;
            }

            return question;
        },

        updateVisibility(question) {


            let externalQs;

            externalQs = this.getQuestionByKey('show_if_question', question.id, true);

            if(externalQs.length) {

                externalQs.forEach(externalQ => {

                    if((externalQ.show_if_answer == question.answer) || (question.is_multiple && question.answers.indexOf(externalQ.show_if_answer) > -1) ) {
                        externalQ.visible = true;
                    }else{
                        externalQ.visible = false;
                        // A hidden question must not block progression with a
                        // stale validation error; it re-validates if re-shown.
                        externalQ.has_error = false;
                        externalQ.can_proceed = true;
                    }

                    this.$store.dispatch('updateAssessmentQuestion', externalQ);

                });


            }


        },

        getQuestionByKey(key, value, multiple, type) {


            const _this = this;

            if(isUndefined(multiple)) {
                multiple = false;
            }

            if(isUndefined(type)) {
                type = 'questions';
            }


            let question = false,
                questions = [];

            for (let sIndex in _this.$store.state.assessment.sections) {

                for (let qIndex in _this.$store.state.assessment.sections[sIndex][type]) {

                    let q = _this.$store.state.assessment.sections[sIndex][type][qIndex];

                    if (q.hasOwnProperty(key)) {

                        if (q[key] == value) {
                            question = q;
                            questions.push(q);
                        }

                    }

                }

            }

            return multiple ? questions : question;

        },

        externalValidation() {

            const _this = this;

            if( !isEmpty(this.$refs) && !isUndefined(this.$refs)) {

                for(const prop in this.$refs) {

                    if(!isUndefined(_this.$refs[prop])) {
                        _this.$refs[prop].externallyValidate();
                    }

                }


            }

        }

    }
}
</script>

<style lang="less">

    .questionWrap {

        background: #fff;
        padding: 27px 0;
        border-bottom: 1px solid var(--border_color);
        border-radius: 0;
        margin: 0;
        color: var(--dark_primary);

        &:first-child {
            border-top: none;
        }

        &.hasError {

            .questionText {

                & > p {

                    &:first-of-type {
                        color: var(--alert_color);
                        transition: color 200ms linear;
                    }
                }

            }
        }

        &.isValid {
            transition: border-color 200ms linear;
        }

        & > .row {
            margin: 0;
            position: relative;
            float: none;
            clear: both;
            display: flex;
            align-items: center;
            gap: 16px;

            @media @flyout {
                flex-wrap: wrap;
                gap: 0;
            }

            &:before, &:after {
                display: none;
            }

            .questionNumberCol {
                flex: 0 0 70px;

                @media @flyout {
                    flex: 0 0 48px;
                }
            }

            .questionText {
                flex: 1 1 100%;

                @media @flyout {
                    flex: 0 0;
                    flex-basis: ~"calc(100% - 48px)";
                }
            }

            & > .inputWrap {
                flex: 0 1 100%;
                display: flex;
                justify-content: flex-end;
                min-width: 300px;

                @media @flyout {
                    flex: 0 0 100%;
                    min-width: 100%;
                    padding: 24px 0 0 48px;
                    justify-content: flex-start;
                }

                @media @mobile {
                    padding: 24px 0 0 0;
                }

                .optionButtons {
                    @media @mobile {
                        width: 100%;
                    }
                }

                .notifyGP {

                    @media @flyout {
                        flex: 0 0 100%;
                        min-width: 100%;
                    }

                }

            }
        }

        .questionNumberCol {

            .questionNumber {
                display: flex;
                justify-content: center;
                align-items: center;
                .rems(17);
                font-weight: 500;
                line-height: 29px;
                color: var(--dark_primary);
                border-radius: 45px;
                border: 1px solid rgba(0, 0, 0, 0.30);
                padding: 8.5px 8px 7.5px 8px;
                width: 30px;
                height: 30px;

            }

        }

        .inputWrap {
            margin: 0;
            padding: 0;
            position: relative;
            float: none;
            clear: both;

        }

        .questionText {
            .rems(17);
            line-height: 22px;
            font-weight: 600;
            color: inherit;
            margin: 0;
            position: relative;
            float: none;
            clear: both;
            min-width: 400px;

            @media @flyout {
                min-width: 0;
            }

            & > p {
                &:first-of-type {
                    font-weight: 700;
                    transition: color 200ms linear;
                }
            }

            p {
                &:last-of-type {
                    margin: 0;
                }
            }

            ul, ol {

                text-transform: none;
                margin: 0;
                padding: 24px 0 0 30px;
                text-align: left !important;

                &:before, &:after {
                    display: none;
                }

                li {
                    .rems(14);
                    line-height: 1.2em;
                    font-weight: 500;
                    padding: 0 0 15px 5px;
                }
            }

            ul {

                padding: 24px 0 0 14px;

                li {
                    list-style: none;
                    position: relative;
                    .rems(14);
                    line-height: 1.2em;
                    font-weight: 500;
                    padding: 0 0 15px 22px;

                    @svg_color: escape(@primary_color);

                    &:before {
                        content: url("data:image/svg+xml; utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' %3E%3Cpath d='M11.3671 3.75949H8.24051V0.632911C8.24051 0.278481 7.94939 0 7.60759 0H4.39241C4.03797 0 3.75949 0.291117 3.75949 0.632911V3.75949H0.632911C0.278481 3.75949 0 4.05061 0 4.39241V7.60759C0 7.96203 0.291117 8.24051 0.632911 8.24051H3.75949V11.3671C3.75949 11.7215 4.05061 12 4.39241 12H7.60759C7.96203 12 8.24051 11.7089 8.24051 11.3671V8.26582H11.3671C11.7215 8.26582 12 7.97471 12 7.63291V4.41772C12 4.05059 11.7089 3.75947 11.3671 3.75947V3.75949Z' fill='@{svg_color}'/%3E%3C/svg%3E");
                        color: var(--primary_color);
                        position: absolute;
                        width: 12px;
                        height: 12px;
                        left: 0;
                        top: 0;
                        margin-top: 1.5px;
                        display: inline-block;
                    }
                }
            }
        }

        .formError {
            color: var(--alert_color);
            padding: 4px 0 8px 0;
            text-transform: none;
            display: none !important;

            p {
                margin: 0;
            }
        }

    }



</style>
