<template>
    <div id="assessmentContent" class="assessmentFormContent">
        <template v-if="!hideSidebarAndInfo">
            <div class="previousCompleted" v-if="previouslyCompleted">
                <div class="alert">
                    <p>
                        It appears you have already completed this assessment. Please check
                        your answers and confirm the answers given still apply to you. If
                        not, please update your answers.
                    </p>
                </div>
                <!-- .alert alertBlue -->
            </div>
            <!-- .previousCompleted -->

            <div class="alertMessage" v-else>
                <div class="alert alertBlue">
                    <p v-if="memberLoginLink">
                        Already a member? <a :href="memberLoginLink">Click here</a> to
                        login.
                    </p>
                </div>
                <!-- .alert alertBlue -->
            </div>
            <!-- .alertMessage -->
        </template>

      <div class="assessmentSubmissionErrors" v-if="submissionErrors.length">
          <div class="error" role="alert">
              <ul v-if="submissionErrors.length > 1">
                  <li
                          v-for="(message, index) in submissionErrors"
                          :key="'submission-error-' + index"
                          v-html="message"
                  ></li>
              </ul>
              <span v-else v-html="submissionErrors[0]"></span>
          </div>
      </div>

        <div v-if="rateLimitedMessage" class="alert alertRed">
            {{ rateLimitedMessage }}
        </div>

        <form
            action=""
            enctype="multipart/form-data"
            method="post"
            class="formContentWrap"
            autocomplete="off"
            ref="mainForm"
            id="mainForm"
        >
            <template v-for="(section, sIndex) in sections">
                <form-section :section="section" :key="'section' + section.id" :show-section-header="false"
                    :rate-limited-message="rateLimitedMessage" @update-section="proceed" v-if="section" />
            </template>
        </form>
        <!-- .formContentWrap -->
    </div>
</template>

<script>

import axios from 'axios';

import { mapGetters } from 'vuex';
import formSection from './form_section';

export default {
    name: "formContent",
    components: {
        formSection
    },
    computed: {
        ...mapGetters({
            sections: 'getAssessmentSections',
        }),
        memberLoginLink() {

            return '/members/login?redirect=' + window.location;

        }
    },
    props: {
        routes: {
            type: Object,
            default: {},
        },
        categoryId: {
            type: Number,
            default: null,
        },
        productId: {
            type: Number,
            default: null,
        },
        previouslyCompleted: {
            type: Boolean,
            default: false,
        },
    },
    data() {
        return {
            loadingStartTimeout: null,
            loadingEndTimeout: null,
            hideSidebarAndInfo: true,
            rateLimitedMessage: false,
            submissionErrors: [],
            lastServerErrorIds: []
        }
    },
    methods: {

        proceed(section) {

            if (this.rateLimitedMessage) {
                return false;
            }

            const _this = this;


            if (section.can_proceed/* && section.submit_assessment*/) {

                this.submitAssessment(section);

            } else {

                if (section.product_selection) {

                    this.updatedSelectedProducts(this.$store.state.assessment.products);

                    if (section.can_proceed) {
                        this.nextSection();
                    }

                } else if (section.can_proceed) {
                    this.nextSection();
                }

            }

        },

        submitAssessment(section) {

            section.loading = true;
            this.$parent.setLoading(true, 'Saving assessment');

            const _this = this;

            const form = this.$refs.mainForm;
            const form_data = new FormData(form);

            form_data.set('assessment_type', this.$store.state.assessment.type);
            form_data.set('category_id', this.categoryId);
            form_data.set('product_id', this.productId);
            form_data.set('review_hash', this.$store.state.reviewHash);
            form_data.set('complete', section.submit_assessment ? '1' : '0');

            axios.post(this.routes['assessment-submit'], form_data, {
                headers: {
                    'Content-Type': 'multipart/form-data'
                }
            })
                .then(function (response) {

                    if (!section.submit_assessment) {
                        _this.submissionErrors = [];
                        _this.applyQuestionErrors({});
                        _this.nextSection();
                        return;
                    }

                    const data = response.data;

                    const errors = data.errors,
                        questionErrors = data.question_errors;

                    if (data.ok) {
                        _this.submissionErrors = [];
                        _this.applyQuestionErrors({});
                        if (data.redirect.length) {
                            window.location.href = data.redirect;
                            return;
                        }

                        _this.$store.dispatch('setCreatedAssessments', data.created_assessments);

                        if (_this.$store.state.assessment.individual_product.id) {

                            _this.sendToBasket(section);

                        } else {
                            axios.post(_this.routes['shop-basket-allowed-products'], {
                                assessment_ids: data.created_assessments,
                                category_id: _this.categoryId,
                                product_id: _this.productId,
                            })
                                .then(function (response) {
                                    _this.nextSection();
                                    _this.$store.dispatch('setAssessmentProducts', response.data);
                                });
                        }


                    } else {
                        _this.submissionErrors = Array.isArray(errors) ? errors : (errors ? [errors] : []);
                        _this.applyQuestionErrors(questionErrors);
                        _this.setLoading(false);
                    }

                })
                .catch(error => {
                    section.loading = false;
                    _this.submissionErrors = ['We were unable to submit your assessment. Please try again.'];
                    _this.applyQuestionErrors({});
                    _this.setLoading(false);
                    if (error.response && error.response.status === 429) {
                        _this.rateLimitedMessage = error.response.data.message || 'You are sending requests too fast. Please wait.';
                    }
                })
                .finally(function () {
                    section.loading = false;
                });

        },

        sendToBasket(section) {

            section.loading = true;

            const individualProduct = this.$store.state.assessment.individual_product;
            console.log(individualProduct);
            const form_data = new FormData();
            form_data.set('ajax', 'true');
            form_data.set('quantity', individualProduct.quantity);
            form_data.set('size', individualProduct.size);
            form_data.set('id', individualProduct.id);
            form_data.set('add-bag', true);

            axios.post(this.routes['add-to-basket'], form_data, {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            }).then(function (response) {
                const data = response.data;
                section.loading = true;
                window.location = '/shop/checkout/basket.php';
            })
                .catch(function (error) {
                    section.loading = true;
                    window.location = '/shop/checkout/basket.php?error=failed_to_add_item';
                });

        },

        updatedSelectedProducts(products) {


            for (const userProp in products) {

                this.$store.dispatch('setAssessmentSelectedProducts', {
                    productProp: userProp,
                    products: products[userProp]
                });

            }


        },

        nextSection() {

            let sectionID = false,
                next = false;

            for (const prop in this.$store.state.assessment.sections) {

                let section = this.$store.state.assessment.sections[prop];

                if (next) {
                    sectionID = section.id;
                    next = false;

                    if (section.product_selection || section.product_confirmation) {
                        this.hideSidebarAndInfo = true;
                    }
                }

                if (section.visible) {
                    next = true;
                }


            }

            if (this.hideSidebarAndInfo) {
                this.$parent.showFormInfo = false;
            } else {
                this.$parent.showFormInfo = true;
            }

            if (sectionID) {
                this.goToSection(sectionID);
            }

        },

        previousSection() {

            let sectionID = false,
                foundVisible = false;

            for (const prop in this.$store.state.assessment.sections) {

                let section = this.$store.state.assessment.sections[prop];

                if (section.visible) {
                    foundVisible = true;
                }

                if (!foundVisible) {
                    sectionID = section.id;
                }

            }

            if (sectionID) {
                this.goToSection(sectionID);
            }

        },

        goToSection(sectionID) {

            const _this = this;

            this.setLoading(true, 'Loading next step');

            clearTimeout(this.loadingStartTimeout);
            clearTimeout(this.loadingEndTimeout);

            this.loadingStartTimeout = setTimeout(() => {

                //assessmentContent
                document.getElementById('assessmentContent').scrollIntoView({
                    behavior: 'smooth'
                });

                this.$store.dispatch('showAssessmentSection', sectionID);


                this.loadingStartTimeout = setTimeout(() => {

                    this.setLoading(false);

                }, 1200);

            }, 800);


        },

        setLoading(loading, message) {
            this.$parent.setLoading(loading, message);
        },

        applyQuestionErrors(questionErrors) {
            this.clearServerQuestionErrors();

            if (!questionErrors || !questionErrors.questions) {
                this.lastServerErrorIds = [];
                return;
            }

            const ids = [];

            Object.keys(questionErrors.questions).forEach(rawId => {
                const message = questionErrors.questions[rawId];
                if (!message) {
                    return;
                }

                const questionId = parseInt(rawId, 10);
                if (Number.isNaN(questionId)) {
                    return;
                }

                this.updateQuestionErrorState(questionId, {
                    has_error: true,
                    error_message: message,
                    can_proceed: false,
                });
                ids.push(questionId);
            });

            this.lastServerErrorIds = ids;

            if (ids.length) {
                this.$nextTick(() => {
                    const target = document.getElementById(`question_wrap_${ids[0]}`);
                    if (target) {
                        target.scrollIntoView({
                            behavior: 'smooth'
                        });
                    }
                });
            }
        },

        clearServerQuestionErrors() {
            if (!this.lastServerErrorIds.length) {
                return;
            }

            this.lastServerErrorIds.forEach(id => {
                this.updateQuestionErrorState(id, {
                    has_error: false,
                    error_message: ''
                });
            });

            this.lastServerErrorIds = [];
        },

        updateQuestionErrorState(questionId, props) {
            const question = this.findQuestionById(questionId);

            if (!question) {
                return;
            }

            const updatedQuestion = {
                ...question,
                ...props
            };

            this.$store.dispatch('updateAssessmentQuestion', updatedQuestion);
        },

        findQuestionById(questionId) {
            const sections = this.$store.state.assessment.sections;
            const numericId = parseInt(questionId, 10);

            if (Number.isNaN(numericId)) {
                return null;
            }

            for (const sectionKey in sections) {
                if (!Object.prototype.hasOwnProperty.call(sections, sectionKey)) {
                    continue;
                }

                const section = sections[sectionKey];

                if (!section || !Array.isArray(section.questions)) {
                    continue;
                }

                const found = section.questions.find(question => parseInt(question.id, 10) === numericId);

                if (found) {
                    return found;
                }
            }

            return null;
        },

    }
}
</script>

<style lang="less">
@import "@site/css/variables.less";
@import "@core/css/mixins.less";
@import "@site/../default/css/base/mixins.less";

.assessmentFormContent {
    grid-area: formarea;
    background: var(--assessment_content_background);
    display: block;
    max-width: 870px;

    padding: 40px 0 80px;
    position: relative;

    @media all and (max-width: 1020px) {
        width: 100%;
        flex: 0 0 100%;
    }

    @media @mobile {
        //text-align: center;
    }

    &>.alert {
        margin: 0 0 50px;
    }

    .formContentWrap {
        width: 100%;
        margin: 0 auto;
        display: block;
    }

    .previousCompleted {
        .alert {
            background: color-mix(in srgb,
                    var(--fade_mixin_color),
                    var(--secondary_color) 40%) !important;
            color: var(--text_color) !important;
        }
    }
}
</style>
