<template>
    <Page>
        <CommunityNav />

        <h2>
            <Icon v="user-chart" />
            <T>census.headerLong</T>
        </h2>

        <template v-if="q === null">
            <section v-if="$isGranted('census')">
                <div class="alert alert-info">
                    <a href="/api/census/export" class="btn btn-outline-secondary btn-sm float-end">
                        <Icon v="download" />
                    </a>

                    <p>{{ countResponses.all }} <T>census.replies</T></p>
                    <ul>
                        <li>{{ countResponses.nonbinary }} <T>census.repliesNonbinary</T></li>
                        <li>{{ countResponses.usable }} <T>census.repliesUsable</T></li>
                        <li>
                            <nuxt-link :to="`/${$config.census.route}/admin`">
                                {{ countResponses.awaiting }} <T>census.repliesAwaiting</T>
                            </nuxt-link>
                        </li>
                    </ul>
                    <ChartSet name="useful responses" :data="countResponses.graphs" init="cumulative" class="mb-3" />
                </div>
            </section>

            <section class="row">
                <div class="col-12 col-lg-6">
                    <T>census.description</T>
                    <T
                        v-if="open"
                        :params="{
                            questions: questions.length,
                            start: start.setLocale($config.locale).toLocaleString(DateTime.DATE_SHORT),
                            end: end.setLocale($config.locale).toLocaleString(DateTime.DATE_SHORT),
                        }"
                    >
                        census.descriptionOpen
                    </T>
                    <T v-else>census.descriptionClosed</T>
                </div>
                <div class="col-12 col-lg-6">
                    <div v-if="Object.keys($config.census.results).length > 0" class="alert alert-info">
                        <ul class="list-unstyled mb-0">
                            <li v-for="(text, link) in $config.census.results" class="h5 m-3">
                                <router-link v-if="typeof text === 'string'" :to="`/blog/${link}`">
                                    <Icon v="file-chart-line" />
                                    {{ text }}
                                </router-link>
                                <div v-else>
                                    <router-link :to="`/blog/${link}`">
                                        <Icon v="file-chart-line" />
                                        {{ text._ }}
                                    </router-link>
                                    <ul class="list-unstyled small">
                                        <template v-for="(subText, subLink) in text">
                                            <li v-if="subLink !== '_'">
                                                <span style="display: inline-block; width: 1.5em"></span>
                                                <router-link :to="`/blog/${subLink}`">
                                                    {{ subText }}
                                                </router-link>
                                            </li>
                                        </template>
                                    </ul>
                                </div>
                            </li>
                        </ul>
                    </div>
                    <CensusShare :text="$t('census.headerLong')" />
                    <CensusSubscribe />
                </div>
            </section>


            <section v-if="open">
                <div v-if="finished" class="alert alert-success">
                    <Icon v="badge-check" :size="2" class="float-start me-2 mt-2" />
                    <T>census.finished</T>
                </div>
                <template v-else>
                    <div class="form-group">
                        <div class="form-check">
                            <label class="form-check-label small">
                                <input v-model="agreement" type="checkbox" class="form-check-input">
                                <T>census.agree</T>
                            </label>
                        </div>
                    </div>
                    <div class="form-group">
                        <button class="btn btn-primary btn-lg" :disabled="!agreement" @click="startSurvey">
                            <T>census.start</T>
                        </button>
                    </div>
                </template>
            </section>
        </template>

        <template v-else-if="q < questions.length">
            <div class="progress my-3">
                <div
                    class="progress-bar"
                    role="progressbar"
                    :style="`width: ${progress}%`"
                    :aria-valuenow="q"
                    aria-valuemin="0"
                    :aria-valuemax="questions.length"
                >
                    {{ q }}/{{ questions.length }}
                </div>
            </div>
            <p class="h4 mt-5 mb-3">
                {{ q + 1 }}. {{ question.question }}
            </p>
            <div v-if="question.instruction" class="alert alert-info small">
                <p v-for="(line, i) in question.instruction" :class="i === question.instruction.length - 1 ? 'mb-0' : ''">
                    <LinkedText :text="line" />
                </p>
            </div>
            <div v-if="question.cw" class="form-check form-switch my-2">
                <label>
                    <input v-model="cw" class="form-check-input" type="checkbox">
                    <Icon v="engine-warning" />
                    <T>census.cw.switch</T>
                </label>
            </div>
            <form ref="questionform" @submit.prevent="q++">
                <div v-if="question.type === 'radio'" :class="['form-group', question.optionsSorted.length > 10 ? 'multi-column' : '']">
                    <div v-for="[option, help] in question.optionsSorted" class="form-check mb-2">
                        <label class="form-check-label small">
                            <input
                                v-model="answers[q]"
                                type="radio"
                                class="form-check-input"
                                :name="`question${q}`"
                                :value="option"
                                required
                            >
                            <span v-if="question.cw && question.cw.includes(option) && !cw" class="badge text-bg-light"><T>census.cw.label</T></span>
                            <span v-else>{{ option }}</span>
                            <span v-if="help" class="text-muted">({{ help }})</span>
                        </label>
                    </div>
                </div>
                <div v-else-if="question.type === 'checkbox'" :class="['form-group', question.optionsSorted.length > 10 ? 'multi-column' : '']">
                    <div v-for="[option, help] in question.optionsSorted" class="form-check mb-2">
                        <label class="form-check-label small">
                            <input v-model="answers[q]" type="checkbox" class="form-check-input" :value="option">
                            <span v-if="question.cw && question.cw.includes(option) && !cw" class="badge text-bg-light"><T>census.cw.label</T></span>
                            <span v-else>{{ option }}</span>
                            <span v-if="help" class="text-muted">({{ help }})</span>
                        </label>
                    </div>
                </div>
                <div v-else-if="question.type === 'text'" class="form-group">
                    <input v-model="answers[q]" type="text" class="form-control" required>
                </div>
                <div v-else-if="question.type === 'number'" class="form-group">
                    <input
                        v-model="answers[q]"
                        type="number"
                        class="form-control"
                        :min="question.min"
                        :max="question.max"
                        required
                    >
                </div>
                <div v-else-if="question.type === 'textarea'" class="form-group">
                    <textarea v-model="answers[q]" class="form-control"></textarea>
                </div>

                <div v-if="question.writein" class="form-group">
                    <input v-model="writins[q]" type="text" class="form-control form-control-sm" :placeholder="$t('census.writein')">
                </div>
            </form>

            <div class="btn-group w-100">
                <button class="btn btn-outline-primary" :disabled="q === 0" @click="q--">
                    <Icon v="arrow-alt-left" />
                    <T>census.prev</T>
                </button>
                <button class="btn btn-primary" :disabled="!stepValid" @click="q++">
                    <T>census.next</T>
                    <Icon v="arrow-alt-right" />
                </button>
            </div>

            <div v-if="$user() && $user().username === 'andrea'" class="mt-4 btn-group w-100">
                <button v-for="(question, i) in questions" :class="['btn', q === i ? 'btn-primary' : 'btn-outline-primary']" :disabled="q === i" @click="q = i">
                    {{ i }}
                </button>
            </div>
        </template>

        <template v-else>
            <div class="progress my-3">
                <div
                    class="progress-bar"
                    role="progressbar"
                    :style="`width: ${progress}%`"
                    :aria-valuenow="q"
                    aria-valuemin="0"
                    :aria-valuemax="questions.length"
                >
                    {{ q }}/{{ questions.length }}
                </div>
            </div>
            <section>
                <div class="alert alert-success">
                    <Icon v="badge-check" :size="2" class="float-start me-2 mt-2" />
                    <T>census.finished</T>
                </div>
            </section>
            <section class="row">
                <div class="col-12 col-lg-6">
                    <CensusShare :text="$t('census.shareButton')" />
                </div>
                <div class="col-12 col-lg-6">
                    <CensusSubscribe />
                </div>
            </section>
        </template>
    </Page>
</template>

<script>
import { buildDict, head, shuffle } from '../src/helpers.ts';
import { DateTime } from 'luxon';

export default {
    async beforeRouteLeave(to, from, next) {
        if (this.q !== null && this.q < this.questions.length) {
            try {
                await this.$confirm(this.$t('census.leave'));
            } catch {
                next(false);
                return;
            }
        }

        next();
    },
    async asyncData({ app }) {
        const finished = await app.$axios.$get('/census/finished');
        const countResponses = await app.$axios.$get('/census/count');

        return {
            finished,
            countResponses,
        };
    },
    data() {
        const questions = this.$config.census.questions.map((q) => {
            q.optionsSorted = q.randomise
                ? [
                    ...q.optionsFirst || [],
                    ...shuffle(q.options),
                    ...q.optionsLast || [],
                ]
                : q.options;
            return q;
        });
        return {
            agreement: false,
            q: null,
            questions,
            answers: buildDict(function* () {
                let i = 0;
                for (const question of questions) {
                    yield [i, question.type === 'checkbox' ? [] : null];
                    i++;
                }
            }),
            writins: buildDict(function* () {
                let i = 0;
                for (const _question of questions) {
                    yield [i, ''];
                    i++;
                }
            }),
            DateTime,
            cw: false,
        };
    },
    head() {
        return head({
            title: this.$t('census.headerLong'),
            description: this.$t('census.description')[0],
            banner: 'img-local/census/census-banner.png',
        }, this.$translator);
    },
    computed: {
        progress() {
            return Math.round(100 * (this.q || 0) / this.questions.length);
        },
        question() {
            return this.questions[this.q];
        },
        stepValid() {
            if (!this.question) {
                return false;
            }
            if (this.writins[this.q] !== '') {
                return true;
            }
            if (this.question.optional) {
                return true;
            }
            if (this.question.type === 'radio') {
                return this.answers[this.q] !== undefined && this.answers[this.q] !== null;
            }
            if (this.question.type === 'checkbox') {
                return this.answers[this.q] !== undefined && this.answers[this.q].length > 0;
            }
            if (this.question.type === 'number') {
                const v = parseInt(this.answers[this.q]);
                return this.answers[this.q] !== '' && v >= this.question.min && v <= this.question.max;
            }
            if (this.question.type === 'text' || this.question.type === 'textarea') {
                return this.answers[this.q] !== '';
            }
            return true;
        },
        start() {
            return DateTime.fromISO(this.$config.census.start).toLocal();
        },
        end() {
            return DateTime.fromISO(this.$config.census.end).toLocal();
        },
        open() {
            const now = DateTime.utc().setZone(this.$config.format.timezone);
            return now >= this.start && now <= this.end;
        },
        finishedEditionKey() {
            return `census-${this.$config.census.edition}-finished`;
        },
    },
    watch: {
        async q(newValue, oldValue) {
            if (this.question && this.question.conditionalOn) {
                const conditionAnswer = this.answers[this.question.conditionalOn];
                const conditionFullfilled = Array.isArray(conditionAnswer)
                    ? conditionAnswer.filter((a) => this.question.conditionalValue.includes(a)).length > 0
                    : conditionAnswer === this.question.conditionalValue;

                if (!conditionFullfilled) {
                    if (newValue > oldValue) {
                        this.q++;
                    } else {
                        this.q--;
                    }
                    return;
                }
            }

            if (this.q === this.questions.length) {
                await this.$post('/census/submit', {
                    answers: JSON.stringify(this.answers),
                    writins: JSON.stringify(this.writins),
                });
                this.finished = true;
                window.localStorage.setItem(this.finishedEditionKey, `${this.$config.census.edition}`);
            }
            this.$nextTick(() => {
                if (this.$refs.questionform) {
                    this.$refs.questionform.querySelector('input,textarea').focus();
                }
            });
        },
    },
    async mounted() {
        if (process.client && !this.$user()) {
            const finishedEdition = window.localStorage.getItem(this.finishedEditionKey) || 0;
            this.finished = parseInt(finishedEdition) === parseInt(this.$config.census.edition);
            if (!this.finished) {
                this.finished = await this.$axios.$get('/census/finished');
            }
        }
    },
    methods: {
        startSurvey() {
            this.q = 0;
        },
    },
};
</script>

<style lang="scss">
    @import "../assets/variables";

    .multi-column {
        columns: 2;
    }
    @include media-breakpoint-up('md', $grid-breakpoints) {
        .multi-column {
            columns: 3;
        }
    }
</style>
