/* eslint no-unused-vars: "off" */
/* eslint no-trailing-spaces: "off" */
/* eslint promise/no-nesting: "off" */
/* eslint max-depth: ["error", 5] */
// Put this file in path/to/plugin/amd/src
// You can call it anything you like

import {call} from 'core/ajax';
import notification from 'core/notification';

import Vue from './vue/vue';

import Debugger from './util/debugger';
import {loadStrings, decodeHtml} from './util/string-helper';
import {processStudyplan} from './studyplan-processor';
import {studyplanTiming} from './util/date-helper';
import {addBrowserButtonEvent} from './util/browserbuttonevents';

import RVComponents from './report-viewer-components';
Vue.use(RVComponents);
import ModalComponents from './modedit-modal';
Vue.use(ModalComponents);

import PortalVue from './portal-vue/portal-vue.esm';
Vue.use(PortalVue);
import BootstrapVue from './bootstrap-vue/bootstrap-vue';
Vue.use(BootstrapVue);


let debug = new Debugger("treestudyplanviewer");

let strings = loadStrings({
    studyplan: {
        studyplanSelectPlaceholder: 'studyplan_select_placeholder',
        loading: "loading@core",
        back: "back",
        studyplanSelect: "studyplan_select",
        selectstudentBtn: "selectstudent_btn",
        studyplanNoneselected: "studyplan_noneselected",
        showoverview: "showoverview"
    },
});

/**
 * Initialize the Page
 * @param {string} selector The selector used to match html element to code
 * @param {number} contextid The context we should attempt to work in (1:1 related to the category)
 * @param {number} categoryid The category we shoud attempt to work in (1:1 related to the context)
 * @param {string} contextname Name of the current context
 */
export function init(selector, contextid, categoryid, contextname) {
    // Make sure the id's are numeric and integer
    if (undefined === contextid || !Number.isInteger(Number(contextid)) || contextid < 1) {
        contextid = 1;
    } else { // Ensure a numeric value instead of string
        contextid = Number(contextid);
    }
    if (undefined === categoryid || !Number.isInteger(Number(categoryid))) {
        categoryid = 0;
    } else { // Ensure a numeric value instead of string
        categoryid = Number(categoryid);
    }

    let app = new Vue({
        el: selector,
        data: {
            selected: {
                planid: 0,
                studentid: 0,
            },
            displayedstudyplan: null,
            activestudyplan: null,
            associatedstudents: [],
            selectedstudent: null,
            studentstudyplan: null,
            loadingstudyplan: false,
            studyplans: [],
            text: strings.studyplan,
            toolbox: {
                right: true,
            },
            usedcontexts: [],
            contextname: decodeHtml(contextname)
        },
        async mounted() {
            call([{
                methodname: 'local_treestudyplan_list_studyplans',
                args: {'context_id': contextid}
            }])[0].then((response) => {
                const timingval = {present: 0, past: 1, future: 2};
                response.sort((a, b) => {
                    const timinga = studyplanTiming(a);
                    const timingb = studyplanTiming(b);

                    const t = timingval[timinga] - timingval[timingb];
                    if (t == 0) {
                        // Sort by name if timing is equal
                        return a.name.localeCompare(b.name);
                    } else {
                        return t;
                    }
                });
                app.studyplans = response;
                // Load studyplan from hash if applicable
                const hash = window.location.hash.replace('#', '');
                const parts = hash.split("-");

                if (!!parts && parts.length > 0 && parts[0] != '') {
                    for (let idx in app.studyplans) {
                        if (app.studyplans[idx].id == parts[0]) {
                            app.selectStudyplan(app.studyplans[idx], parts[1]);
                            break;
                        }
                    }
                }
                return;
            }).catch(notification.exception);
            call([{
                methodname: 'local_treestudyplan_list_available_categories',
                args: {operation: 'view', 'refcontext_id': contextid}
            }])[0].then((response) => {
                const contexts = [];
                for (const ix in response) {
                    const cat = response[ix];
                    if (cat.studyplancount > 0 || cat.context_id == contextid) {
                        contexts.push(cat);
                    }
                }
                app.usedcontexts = contexts;
                return;
            }).catch(notification.exception);
            addBrowserButtonEvent(this.navChanged, this.navChanged);
        },
        computed: {
            dropdownTitle() {
                if (this.activestudyplan && this.activestudyplan.name) {
                    return this.activestudyplan.name;
                } else {
                    return this.text.studyplanSelectPlaceholder;
                }
            },
            contextid() {
                return contextid;
            }
        },
        methods: {
            navChanged() {
                const hash = window.location.hash.replace('#', '');
                const parts = hash.split("-");
                debug.log("Navigation changed", hash, parts);

                if (!!parts && parts.length > 0) {
                    const planid = Number(parts[0]);
                    const studentid = (parts.length > 1) ? Number(parts[1]) : 0;

                    debug.log("Selected ids", planid, studentid, this.selected.planid, this.selected.studentid);
                    if (planid == 0) {
                        if (planid != this.selected.planid) {
                            this.closeStudyplan(false);
                        }
                    } else if (this.selected.planid != planid || (studentid == 0 && this.selected.studentid != 0)) {
                        debug.info("Requested plan changed - loading studyplan");
                        for (let idx in app.studyplans) {
                            const plan = this.studyplans[idx];
                            if (Number(plan.id) == planid) {
                                this.selectStudyplan(plan, studentid, false);
                                break;
                            }
                        }
                    } else if (this.selected.studentid != studentid) {
                        for (const group of app.associatedstudents) {
                            for (const student of group.users) {
                                if (Number(student.id) == studentid) {
                                    app.showStudentView(student, false);
                                    break;
                                }
                            }
                        }
                    }
                } 
            },
            switchContext(ctxid) {
                const params = new URLSearchParams(location.search);
                params.delete('categoryid');
                params.set('contextid', ctxid);
                setTimeout(() => {
                    // Reload page in a timeout to give other form javasccript the change to remove the beforeunload handler.
                    window.location.href = window.location.pathname + "?" + params.toString();
                }, 50);
            },
            closeStudyplan(updatehash = true) {
                app.selected.planid = 0;
                app.selected.studentid = 0;
                app.activestudyplan = null;
                app.associatedstudents = [];
                app.studentstudyplan = [];
                app.displayedstudyplan = null;
                if (updatehash) {
                    window.location.hash = '';
                }
            },

            selectStudyplan(studyplan, studentid, updatehash = true) {
                app.selected.planid = Number(studyplan.id);
                app.selected.studentid = studentid ? Number(studentid) : 0;
                // Fetch studyplan
                app.loadingstudyplan = true;
                app.associatedstudents = [];
                app.selectedstudent = null;
                app.studentstudyplan = null;
                call([{
                    methodname: 'local_treestudyplan_get_studyplan_resultmap',
                    args: {id: studyplan.id}
                }])[0].then((response) => {
                    app.activestudyplan = processStudyplan(response, true);

                    call([{
                        methodname: 'local_treestudyplan_all_associated_grouped',
                        args: {'studyplan_id': studyplan.id}
                    }])[0].then((response) => {
                        app.associatedstudents = response;
                        let foundstudent = false;
                        if (studentid) {
                            for (const group of app.associatedstudents) {
                                for (const student of group.users) {
                                    if (student.id == studentid) {
                                        foundstudent = true;
                                        app.showStudentView(student, updatehash);
                                        break;
                                    }
                                }
                            }
                        }
                        if (!foundstudent) {
                            app.selected.studentid = 0;
                            if (updatehash) {
                                window.location.hash = app.activestudyplan.id;
                            }
                            app.displayedstudyplan = app.activestudyplan;
                            app.loadingstudyplan = false;
                        }
                        return;
                    }).catch(notification.exception);
                    return;
                }).catch(function(error) {
                    notification.exception(error);
                    app.loadingstudyplan = false;
                });
            },
            showStudentView(student, updatehash = true) {
                app.selected.studentid = student ? Number(student.id) : 0;
                if (student) {
                    app.selectedstudent = student;
                    app.studentstudyplan = null;
                    app.loadingstudyplan = true;
                    call([{
                        methodname: 'local_treestudyplan_get_user_studyplan',
                        args: {userid: student.id, studyplanid: app.selected.planid}
                    }])[0].then((response) => {
                        app.studentstudyplan = processStudyplan(response, false);
                        app.displayedstudyplan = app.studentstudyplan;
                        app.loadingstudyplan = false;
                        if (updatehash) {
                            window.location.hash = app.activestudyplan.id + "-" + student.id;
                        }
                        return;
                    }).catch((error) => {
                        notification.exception(error);
                        app.loadingstudyplan = false;
                    });
                } else {
                    this.showOverview(updatehash);
                }
            },
            showOverview(updatehash = true) {
                app.selected.studentid = 0;
                app.selectedstudent = null;
                app.studentstudyplan = null;
                app.displayedstudyplan = app.activestudyplan;
                if (updatehash) {
                    window.location.hash = app.activestudyplan.id;
                }
            }

        },
        template: `
        <div>
            <div class='vue-loader' v-show='false'>
                <div class="spinner-border text-primary" role="status">
                    <span class="sr-only">Loading...</span>
                </div>
            </div>
            <div v-cloak>
                <div v-if='!activestudyplan && usedcontexts' class='ml-3 mb-3 s-context-selector'>
                    <b-form-select :text='contextname' :value="contextid" @change='switchContext'
                        :class="(!(usedcontexts.length)) ? 'text-primary' : ''">
                        <b-form-select-option v-if='!(usedcontexts.length)' :value="contextid"
                            :class="'text-primary'">
                            <span>{{text.loading}}...</span></b-form-select-option>
                        <b-form-select-option v-for='ctx in usedcontexts' :key='ctx.id' :value="ctx.context_id"
                            :class="(ctx.studyplancount > 0) ? 'font-weight-bold' : ''"
                        ><span v-for="(p, i) in ctx.category.path"><span v-if="i>0"> / </span><span v-html="p"></span></span>
                        <span>({{ ctx.studyplancount }})</span></b-form-select-option>
                    </b-form-select>
                    <div v-if="!(usedcontexts.length)"
                        style="position: relative; top: 0.3rem; width: 1.2rem; height: 1.2rem; font-size: 0.7rem;"
                        class="spinner-border text-primary" role="status"></div>
                </div>
                <h3 v-else><span v-html="contextname"></span></h3>
                <div class="m-buttonbar" style="margin-bottom: 1em;">
                    <template v-if="displayedstudyplan">
                        <a href='#' @click.prevent='closeStudyplan'
                            ><i style='font-size: 150%;' class='fa fa-chevron-left'></i> {{text.back}}</a>
                        <span>{{text.studyplanSelect}}</span>&nbsp;
                        <b-form-select lazy :text='dropdownTitle' :value='displayedstudyplan.id'>
                            <b-form-select-option
                                v-for='(studyplan, planindex) in studyplans'
                                :key='studyplan.id'
                                @click='selectStudyplan(studyplan)'
                                :value='studyplan.id'
                                ><span v-html="studyplan.display.name"></span
                            ></b-form-select-option>
                        </b-form-select>&nbsp;
                        <s-studyplan-details
                            v-model="displayedstudyplan"
                            v-if="displayedstudyplan.description"
                        ></s-studyplan-details>
                        <div class="flex-grow-1"><!-- Spacer to align student selector right --></div>
                        <div>
                            <span>{{text.selectstudentBtn}}</span>
                            <s-prevnext-selector
                                :options="associatedstudents"
                                title="firstname"
                                v-model="selectedstudent"
                                defaultselectable
                                grouped
                                optionsfield='users'
                                arrows
                                @change="showStudentView"
                                class="ml-2"
                                variant="primary"
                                >
                                <template v-slot="{value}">{{value.firstname}} {{value.lastname}}</template>
                                <template #defaultlabel><span class='text-primary'>{{text.showoverview}}</span></template>
                            </s-prevnext-selector>
                        </div>
                    </template>
                </div>
                <div class='t-studyplan-container'>
                    <h2 v-if='displayedstudyplan&& selectedstudent'
                        >{{selectedstudent.firstname}} {{selectedstudent.lastname}} - <span
                            v-html="displayedstudyplan.display.name"></span></h2>
                    <h2 v-else-if='displayedstudyplan'>{{text.showoverview}} - <span
                            v-html="displayedstudyplan.display.name"></span></h2>
                    <r-studyplan v-if='!loadingstudyplan && displayedstudyplan'
                                v-model='displayedstudyplan' :teachermode='!selectedstudent'
                        ></r-studyplan>
                    <div v-else-if='loadingstudyplan' class="spinner-border text-primary" role="status">
                        <span class="sr-only">Loading...</span>
                    </div>
                    <div v-else class='t-studyplan-notselected'>
                        <p>{{text.studyplanNoneselected}}</p>
                        <b-card-group deck>
                            <s-studyplan-card
                                v-for='(studyplan, planindex) in studyplans'
                                :key='studyplan.id'
                                v-model='studyplans[planindex]'
                                open
                                @open='selectStudyplan(studyplan)'
                                ></s-studyplan-card>
                        </b-card-group>
                    </div>
                </div>
            </div>
        </div>
        `
    });
}
