<template>
    <div id="assessmentContent" class="assessmentFormContent">
        <div class="previouslyCompletedBanner" v-if="hasPreviouslyCompleted">
            <div class="alert alertBlue">
                <p>
                    You previously completed this assessment on {{ previouslyCompletedAt }}.
                    If your answers haven't changed, you can confirm them now to skip re-entering them.
                </p>
            </div>
        </div>
        <!-- .previouslyCompletedBanner -->

        <div class="draftBanner" v-if="hasDraft && !hasPreviouslyCompleted">
            <div class="alert alertBlue">
                <p>
                    You have a saved draft from {{ draftUpdatedAt }}. It expires on {{ draftExpiresAt }}.
                    Your previous answers have been restored.
                </p>
            </div>
        </div>
        <!-- .draftBanner -->

        <template v-if="!hideSidebarAndInfo">
            <div class="alertMessage" v-if="!previouslyCompleted && !hasPreviouslyCompleted">
                <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"
                  >{{ message }}</li>
              </ul>
              <span v-else>{{ 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" :is-first-section="sIndex === 0"
                    :previously-completed="hasPreviouslyCompleted"
                    :is-confirming="isConfirming"
                    @update-section="proceed" @go-back="previousSection"
                    @confirm-unchanged="confirmUnchanged" 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,
        },
        hasDraft: {
            type: Boolean,
            default: false,
        },
        draftUpdatedAt: {
            type: String,
            default: '',
        },
        draftExpiresAt: {
            type: String,
            default: '',
        },
        hasPreviouslyCompleted: {
            type: Boolean,
            default: false,
        },
        previouslyCompletedAt: {
            type: String,
            default: '',
        },
    },
    data() {
        return {
            loadingStartTimeout: null,
            loadingEndTimeout: null,
            hideSidebarAndInfo: true,
            rateLimitedMessage: false,
            submissionErrors: [],
            lastServerErrorIds: [],
            isConfirming: false
        }
    },
    mounted() {
        if (this.hasDraft) {
            this.$nextTick(() => {
                this.reEvaluateConditionalVisibility();
            });
        }
    },
    methods: {

        escapeHtml(text) {
            if (!text) return '';
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        },

        reEvaluateConditionalVisibility() {
            const sections = this.$store.state.assessment.sections;
            for (const sIndex in sections) {
                const section = sections[sIndex];
                if (!section || !Array.isArray(section.questions)) {
                    continue;
                }
                section.questions.forEach(question => {
                    if (!question.answer && (!question.answers || !question.answers.length)) {
                        return;
                    }
                    // Find any questions whose visibility depends on this question's answer
                    section.questions.forEach(depQ => {
                        if (depQ.show_if_question === question.id) {
                            depQ.visible = (
                                depQ.show_if_answer === question.answer
                                || (question.is_multiple && question.answers && question.answers.indexOf(depQ.show_if_answer) > -1)
                            );
                            this.$store.dispatch('updateAssessmentQuestion', depQ);
                        }
                    });
                    // Also check across all sections for cross-section conditionals
                    for (const otherIndex in sections) {
                        if (otherIndex === sIndex) continue;
                        const otherSection = sections[otherIndex];
                        if (!otherSection || !Array.isArray(otherSection.questions)) continue;
                        otherSection.questions.forEach(depQ => {
                            if (depQ.show_if_question === question.id) {
                                depQ.visible = (
                                    depQ.show_if_answer === question.answer
                                    || (question.is_multiple && question.answers && question.answers.indexOf(depQ.show_if_answer) > -1)
                                );
                                this.$store.dispatch('updateAssessmentQuestion', depQ);
                            }
                        });
                    }
                });
            }
        },


        confirmUnchanged() {
            if (this.isConfirming) return;

            this.isConfirming = true;
            this.submissionErrors = [];
            this.$parent.setLoading(true, 'Confirming assessment');

            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', '1');

            const _this = this;

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

                    if (data.ok) {
                        _this.submissionErrors = [];
                        _this.$store.dispatch('setCreatedAssessments', data.created_assessments);

                        if (_this.$store.state.assessment.individual_product.id) {
                            _this.sendToBasket({ loading: false });
                        } else if (data.redirect.length) {
                            window.location.href = data.redirect;
                        } 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.$store.dispatch('setAssessmentProducts', response.data);
                                    _this.skipToProductSection();
                                })
                                .catch(function (error) {
                                    _this.submissionErrors = ['Unable to load available products. Please try again.'];
                                    _this.isConfirming = false;
                                    _this.$parent.setLoading(false);
                                });
                        }
                    } else {
                        _this.submissionErrors = Array.isArray(errors) ? errors : (errors ? [errors] : []);
                        _this.applyQuestionErrors(questionErrors);
                        _this.isConfirming = false;
                        _this.setLoading(false);
                    }
                })
                .catch(function () {
                    _this.submissionErrors = ['Unable to confirm assessment. Please review and update your answers.'];
                    _this.isConfirming = false;
                    _this.setLoading(false);
                });
        },

        skipToProductSection() {
            const sections = this.$store.state.assessment.sections;
            let productSectionId = null;

            for (const prop in sections) {
                if (sections[prop].product_selection) {
                    productSectionId = sections[prop].id;
                    break;
                }
            }

            if (productSectionId) {
                this.hideSidebarAndInfo = true;
                this.$parent.showFormInfo = false;
                this.goToSection(productSectionId);
            } else {
                // No product selection section found - clear loading state and show error
                this.submissionErrors = ['Unable to load product selection. Please refresh the page and try again.'];
                this.isConfirming = false;
                this.$parent.setLoading(false);
            }
        },

        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] : []);

                        // Append per-question error details so the user knows which answers were flagged
                        if (questionErrors && questionErrors.questions) {
                            Object.keys(questionErrors.questions).forEach(rawId => {
                                const message = questionErrors.questions[rawId];
                                const questionId = parseInt(rawId, 10);
                                if (!Number.isNaN(questionId) && message) {
                                    const question = _this.findQuestionById(questionId);
                                    if (question && question.question_text) {
                                        const temp = document.createElement('div');
                                        temp.innerHTML = question.question_text;
                                        const text = (temp.textContent || temp.innerText || '').trim();
                                        _this.submissionErrors.push(text + ': ' + message);
                                    }
                                }
                            });
                        }

                        _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;
            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>
