/* eslint no-var: "error"*/
/* eslint no-console: "off"*/
/* eslint camelcase: "off" */
/* eslint-disable no-trailing-spaces */
/* eslint-env es6*/
// Put this file in path/to/plugin/amd/src

import {loadStrings} from './util/string-helper';
import {formatDate, studyplanDates, studyplanTiming} from './util/date-helper';
import FitTextVue from './util/fittext-vue';
import {settings} from "./util/settings";

export default {

    install(Vue /* ,options */) {
        Vue.use(FitTextVue);

        let strings = loadStrings({
            studyplancard: {
                open: "open",
                noenddate: "noenddate",
                idnumber: "studyplan_idnumber",
                description: "studyplan_description",
                completed: "completed",
                details: "studyplan_details",
                suspended: "suspended",
            },
            details: {
                details: "studyplan_details",
            },
            extrafields: {
                show: "show@core"
            },
            prevnext: {
                prev: "prev@core",
                previous: "previous@core",
                next: "next@core",
                select: "selectanoptions@core",
            }
        });
        // Create new eventbus for interaction between item components
        const ItemEventBus = new Vue();

        Vue.component('s-studyplan-card', {
            props: {
                value: {
                    type: Object,
                },
                open: {
                    type: Boolean
                },
                ignoresuspend: {
                    type: Boolean,
                    'default': false,
                },
            },
            data() {
                return {
                    text: strings.studyplancard
                };
            },
            computed: {
                timeless() {
                    const plan = this.value;
                    if (!plan.pages || plan.pages.length == 0 || plan.pages[0].timeless) {
                        return true;
                    } else {
                        return false;
                    }
                },
                timing() {
                    return studyplanTiming(this.value);
                },
                dates() {
                    const dates = studyplanDates(this.value);
                    return {
                        start: formatDate(dates.start),
                        end: (dates.end) ? formatDate(dates.end) : this.text.noenddate,
                    };
                },
                suspended() {
                    return (this.value.suspended && !this.ignoresuspend);
                }

            },
            methods: {
                onOpenClick(e) {
                    this.$emit('open', e);
                }
            },
            template: `
            <b-card
                :class="'s-studyplan-card timing-' + timing + (suspended?' s-suspended':'')"
            >
                <template #header></template>
                <div class='s-studyplan-card-content'>
                    <div class='s-studyplan-card-icon'><img :src='value.icon'></div>
                    <div class='s-studyplan-card-info'>
                        <div class='s-studyplan-card-titlebar'>
                            <b-card-title>
                                <a class='title' v-if='open && !suspended'
                                    href='#' @click.prevent='onOpenClick($event)'><span v-html="value.display.name"></span></a>
                                <template v-else><span v-html="value.display.name"></span></template>
                                <div v-if="suspended" class='text-danger'
                                    ><fittext maxsize="12pt">{{text.suspended}}</fittext></div>
                            </b-card-title>
                            <div class='s-studyplan-card-titleslot'><slot name='title'></slot></div>
                        </div>
                        <div class='s-studyplan-card-idnumber' v-if='value.idnumber'>
                        {{ text.idnumber }}: {{ value.idnumber }}
                        </div>
                        <s-progress-bar
                            v-if='!suspended && value.progress !== undefined && value.progress !== null'
                            v-model="value.progress"
                        ></s-progress-bar>
                    </div>

                </div>
                <slot></slot>
                <template #footer>
                    <span v-if="!timeless" :class="'t-timing-'+timing" v-html="dates.start + ' - '+ dates.end"></span>
                    <span class="s-studyplan-card-buttons">
                    <slot name='footer'></slot>
                    <s-studyplan-details
                        v-model="value"
                        v-if="value.description"
                    ><i class='fa fa-info-circle'></i></s-studyplan-details>
                    <b-button style="float:right;" v-if='open && !suspended' variant='primary'
                        @click.prevent='onOpenClick($event)'>{{ text.open }}</b-button>
                    </span>
                </template>
            </b-card>
            `,
        });

        Vue.component('s-progress-bar', {
            props: {
                value: {
                    type: Number,
                },
                min: {
                    type: Number,
                    default() {
                        return 0;
                    }
                },
                max: {
                    type: Number,
                    default() {
                        return 1;
                    }
                }
            },
            data() {
                return {
                    text: strings.studyplancard
                };
            },
            computed: {
                width_completed() {
                    if (this.value) {
                        const v = ((this.value - this.min) / (this.max - this.min));
                        return v * 100;
                    } else {
                        return 0;
                    }
                },
                width_incomplete() {
                    if (this.value) {
                        const v = ((this.value - this.min) / (this.max - this.min));
                        return (1 - v) * 100;
                    } else {
                        return 100;
                    }
                },
                percentage_complete() {
                    if (this.value) {
                        const v = ((this.value - this.min) / (this.max - this.min));
                        return Math.round(v * 100) + "%";
                    } else {
                        return "0%";
                    }
                }
            },
            template: `
            <div class='s-studyplan-card-progress' >
                <div class="s-studyplan-card-progressbar"
                ><span v-if="width_completed > 0"
                    :style="{width: width_completed+'%'}"
                    class='s-studyplan-card-progress-segment s-studyplan-card-progress-completed'
                ></span
                ><span :style="{width: width_incomplete+'%'}"
                    class='s-studyplan-card-progress-segment s-studyplan-card-progress-incomplete'
                ></span
                ></div>
                <div class="s-studyplan-card-progresstext">
                    {{ percentage_complete}} {{ text.completed.toLowerCase() }} 
                </div>
        </div>
            `,
        });

        /*
        * S-STUDYLINE-HEADER-HEADING
        * The only reasing this is not a simple empty div, is the fact that the header height
        * needs to match that of the period headers
        */
        Vue.component('s-studyline-header-heading', {
            props: {
                identifier: {
                    type: Number, // Page reference.
                    default() {
                        return 0;
                    }
                }
            },
            data() {
                return {
                    layerHeights: {}
                };
            },
            created() {
                // Listener for the signal that a new connection was made and needs to be drawn
                // Sent by the incoming item  - By convention, outgoing items are responsible for drawing the lines
                ItemEventBus.$on('headerHeightChange', this.onHeaderHeightChange);
            },
            computed: {

            },
            methods: {
                onHeaderHeightChange(newheight, identifier) {
                    if (this.identifier == identifier) {
                        if (this.$refs.main) {
                            this.$refs.main.style.height = `${newheight}px`;
                        }
                    }
                }
            },
            template: `
            <div class="s-studyline-header-heading" ref="main" :data-id="identifier"><slot></slot></div>
            `,
        });

        Vue.component('s-studyline-header-period', {
            props: {
                value: {
                    type: Object, // Dict with layer as index
                },
                identifier: {
                    type: Number, // Page reference.
                    default() {
                        return 0;
                    }
                },
                mode: {
                    type: String,
                    'default': "view",
                }
            },
            mounted() {
                const self = this;
                if (self.value.period == 1) {
                    self.resizeListener = new ResizeObserver(() => {
                        if (self.$refs.main) {
                            const size = self.$refs.main.getBoundingClientRect();
                            ItemEventBus.$emit('headerHeightChange', size.height, self.identifier);
                        }
                    }).observe(self.$refs.main);
                }
            },
            unmounted() {
                if (this.resizeListener) {
                    this.resizeListener.disconnect();
                }
            },
            computed: {
                startdate() {
                    return formatDate(this.value.startdate);
                },
                enddate() {
                    return formatDate(this.value.enddate);
                },
                current() {
                    if (this.value && this.value.startdate && this.value.enddate) {
                        const now = new Date();
                        const pstart = new Date(this.value.startdate);
                        const pend = new Date(this.value.enddate);
                        return (now >= pstart && now < pend);
                    } else {
                        return false;
                    }
                }

            },
            data() {
                return {
                };
            },
            template: `
            <div :class="'s-studyline-header-period '" ref="main" :data-id="identifier"
                ><p><abbr :id="'s-period-'+value.id" :title="value.fullname"><span v-html="value.display.shortname"></span></abbr>
                <b-tooltip
                    :target="'s-period-'+value.id" triggers="hover"
                    ><span v-html="value.display.fullname"></span><br>
                    <span v-if="!value.timeless" class="s-studyline-header-period-datespan">
                        <span class="date">{{ startdate }}</span> - <span class="date">{{ enddate }}</span>
                    </span>
                </b-tooltip>
                <slot></slot
                ><p v-if="!value.timeless && value.startdate > 0"
                    class="s-studyline-header-period-datespan small">
                    <span class="date">{{ startdate }}</span>
                     - <span class="date" v-if="value.enddate > 0">{{ enddate }}</span><span class="date" v-else>&infin;</span>
                </p>
                <div v-if="current && mode == 'view'" class='s-studyline-period-highlight'></div>
            </div>
            `,
        });


        Vue.component('s-studyplan-details', {
            props: {
                value: {
                    type: Object,
                },
                variant: {
                    type: String,
                    default() {
                        return "info";
                    }
                },
                pill: {
                    type: Boolean,
                    default() {
                        return false;
                    }
                },
                size: {
                    type: String,
                    default() {
                        return "";
                    }
                }
            },
            data() {
                return {
                    text: strings.details,
                };
            },
            template: `
            <span>
                <b-button 
                    :size="size"
                    :pill="pill"
                    :variant="variant" 
                    v-b-modal="'modal-description-'+value.id"
                ><slot><i class='fa fa-info-circle'></i>
                {{ text.details}}</slot>
                </b-button>
                <b-modal
                    scrollable
                    centered
                    ok-only
                    content-class="s-studyplan-details"
                    :id="'modal-description-'+value.id"
                    >
                    <template #modal-title>
                        <span v-html="value.display.name"></span>
                    </template>
                    <b-container>
                        <b-row>
                            <b-col cols="4"><div class='s-studyplan-card-icon'><img :src='value.icon'></div></b-col>
                            <b-col cols="8" class="pl-1">
                                <span v-html="value.display.description"></span>
                            </b-col>
                        </b-row>
                    </b-container>
                </b-modal>
            </span>
            `,
        });

        Vue.component('s-course-extrafields', {
            props: {
                value: {
                    type: Array,
                },
                variant: {
                    type: String,
                    default() {
                        return "info";
                    }
                },
                position: {
                    type: String,
                    default() {
                        return "below";
                    }
                },
                size: {
                    type: String,
                    default() {
                        return "";
                    }
                }
            },
            data() {
                return {
                    text: strings.extrafields,
                };
            },
            computed: {
                fields() {
                    const fields = [];
                    for (const ix in this.value) {
                        const field = this.value[ix];
                        if (field.position == this.position && field.value && field.value.length > 0) {
                            fields.push(field);
                        }
                    }
                    return fields;
                },
            },
            methods: {
                displaydate(field) {
                    return formatDate(field.value, false);
                },
            },
            template: `
            <div :class="'s-course-extrafields ' + ((fields.length>0)?position:'empty')">
                <table v-if="fields.length > 0">
                    <tr v-for="field in fields">
                        <td><span class='title' v-if='field.title'>{{ field.title}}</span></td>
                        <td>
                        <span v-if='field.type == "date"' class="value date">{{ displaydate(field) }}</span>
                        <span v-else-if='field.type == "checkbox"' 
                        :class="'value ' + (field.checked?'true':'false')">{{ field.value }}</span>
                        <span v-else-if='field.type == "textarea"'>
                            <a  class='text-info' 
                                @click.prevent.stop=""
                                href='#' 
                                v-b-modal="field.courseid+'_'+field.fieldname">{{text.show}}...</a>
                            <b-modal
                                :id="field.courseid+'_'+field.fieldname"
                                :title="field.title""
                                scrollable
                                centered
                                ok-only
                                ><span v-html="field.value"></span
                            ></b-modal>
                        </span>
                        <span v-else class="value"><span v-html="field.value"></span></span>
                        </td>
                    </tr>
                </table>
            </div>
            `,
        });

        Vue.component('s-prevnext-selector', {
            props: {
                value: {
                    type: Object, 
                    default() {
                        return null;
                    }
                },
                options: {
                    type: Array,
                },
                grouped: {
                    type: Boolean,
                    'default': false,
                },
                titlefield: {
                    type: String,
                    'default': "title",
                },
                labelfield: {
                    type: String,
                    'default': "label",
                },
                optionsfield: {
                    type: String,
                    'default': "options",
                },
                defaultselectable: {
                    type: Boolean,
                    'default': false,
                },
                variant: {
                    type: String,
                    'default': "",
                },
                arrows: {
                    type: Boolean,
                    'default': false,
                },
            },
            data() {
                return {
                    settings: settings,
                    text: strings.prevnext,
                };
            },
            computed: {
                fields() {
                    const f = [];
                    if (this.defaultselectable) {
                        f.push(null);
                    }
                    if (this.grouped) {
                        for (const gix in this.options) {
                            const group = this.options[gix];
                            for (const ix in group[this.optionsfield]) {
                                const v = group[this.optionsfield][ix];
                                f.push(v);
                            }
                        }
                    } else {
                        for (const ix in this.options) {
                            const v = this.options[ix];
                            f.push(v);
                        }
                    }
                    return f;
                },
                bubblevalue: {
                    get() {
                        return (this.value) ? this.value : null;
                    },
                    set(v) {
                        this.$emit('input', (v) ? v : null);
                    },
                }
            },
            methods: {
                atFirst() {
                    if (this.fields.length > 0) {
                        return this.fields[0] == this.value;
                    }
                    return true; // Since it disables the button, do so if pressing it would make no sense.
                },
                atLast() {
                    if (this.fields.length > 0) {
                        const l = this.fields.length - 1;
                        return this.fields[l] == this.value;
                    }
                    return true; // Since it disables the button, do so if pressing it would make no sense.
                },
                prev() {
                    if (this.fields.length > 0) {
                        const index = this.fields.indexOf(this.value);
                        if (index > 0) {
                            this.$emit("input", this.fields[index - 1]);
                            this.$emit("change", this.fields[index - 1]);
                        }
                    }
                },
                next() {
                    if (this.fields.length > 0) {
                        const index = this.fields.indexOf(this.value);
                        const l = this.fields.length - 1;
                        if (index >= 0 && index < l) {
                            this.$emit("input", this.fields[index + 1]);
                            this.$emit("change", this.fields[index + 1]);
                        }
                    }
                },
                selectedchanged(value) {
                    this.$emit("change", value);
                }
            },
            template: `
            <div :class="'s-prevnext-selector '">
                <template v-if="settings.showprevnextarrows"
                ><b-button :variant='variant' @click="prev" :disabled="atFirst()"
                    ><i v-if='arrows' class='fa fa-caret-left s-prevnext-arrow'></i
                    ><template v-else>{{text.prev}}</template></b-button
                >&nbsp;</template
                ><b-form-select v-model="bubblevalue"
                    @change='selectedchanged'
                    ><b-form-select-option
                            :disabled="!defaultselectable"
                            :value="null"
                            :class="(defaultselectable)?'font-italic text-primary ':'font-italic'"
                            ><slot name="defaultlabel">{{text.select}}</slot></b-form-select-option
                    ><template v-if="grouped"
                        ><template v-for="(g,gi) in this.options"
                            ><b-form-select-option-group
                                v-if="g[optionsfield] && g[optionsfield].length > 0"
                                :label="g[labelfield]"
                                ><b-form-select-option 
                                    v-for="(o,i) in g[optionsfield]" 
                                    :key="i"
                                    :value="o"
                                    ><slot :value="o">{{o[titlefield]}}</slot></b-form-select-option>
                            </b-form-select-option-group
                        ></template
                    ></template
                    ><template v-else>
                        <b-form-select-option 
                            v-for="(o,i) in this.options" 
                            :key="i"
                            :value="o"
                            ><slot :value="o">{{o[titlefield]}}</slot></b-form-select-option
                    ></template
                ></b-form-select
                ><template v-if="settings.showprevnextarrows"
                >&nbsp;<b-button :variant='variant' @click="next" :disabled="atLast()"
                    ><i v-if='arrows' class='fa fa-caret-right s-prevnext-arrow'></i
                    ><template v-else>{{text.next}}</template></b-button
                ></template
            ></div>
            `,
        });


    }
};