import { HttpClient } from 'aurelia-fetch-client';

import { inject } from 'aurelia-framework';
import { FactBoxConfiguration } from './configuration';


@inject(FactBoxConfiguration)

export class FactboxEditor {

    // user's choices
    pdfURL = '';
    jsonURL = '';

    pdfWorker = undefined;

    selectedLanguage = 'de';
    selectedLayout = 1;
    selectedIcon = 0;
    selectedSize = 1000;
    selectedSizeId = 1;

    maxClasses = 6;
    iaGroupSpacing = 0.0;
    iaClassSpacing = 0;

    fontsloaded = 0;

    constructor(configuration) {

        for (let key in configuration) {
            this[key] = configuration[key];
        }

        let option = window.location.search.substr(1, 4);
        if (option === 'lang') {
            this.selectedLanguage = window.location.search.substr(6, window.location.search.length - 1);
        } else {
            this.languageChanged();
        }

        this.httpClient = new HttpClient();
        this.httpClient.configure(config => {
            config.useStandardConfiguration();
        });
    }

    attached() {
        for (let md in this.fontData) {
            let cfd = this.fontData[md];

            this.httpClient.fetch(cfd.url)
                .then(response => response.arrayBuffer())
                .then(data => {
                    cfd.data = data;
                    this.fontsloaded += 1;

                    if (this.fontsloaded === Object.keys(this.fontData).length) {
                        this.createWorker();
                    }
                });
        }
    }

    createWorker() {
        // employ a proper pdf worker after all fonts are loaded
        if (window.Worker) {

            this.pdfWorker = new Worker('src/pdfWorker.js');

            this.pdfWorker.onmessage = (e) => {  // I need 'this'
                this.pdfURL = e.data;
            };

        } else {
            // console.log('window.Worker is not supported by this browser');
        }
    }


    titleChanged() {
        this.updateExportData();
    }

    languageChanged() {
        window.history.replaceState(
            {},
            this.labels.appTitle[this.selectedLanguage],
            window.location.origin + window.location.pathname + '?lang=' + this.selectedLanguage
        );
        document.title = this.labels.appTitle[this.selectedLanguage];
        if (this.pdfWorker) {
            this.updatePDF();
        }
    }

    iconArrayLayoutChanged(e) {
        this.updatePDF();
    }

    updatePDF() {

        if (this.pdfURL) {
            window.URL.revokeObjectURL(this.pdfURL);
        }

        this.pdfWorker.postMessage(
            {
                'appTitle':         this.labels.appTitle,
                'baseFontSize':     this.baseFontSize,
                'baseClass':        this.baseClass,
                'classes':          this.classes,
                'description':      this.description,
                'faq':              this.faq,
                'fontData':         this.fontData,
                'fontRatios':       this.fontRatios,
                'hcVersion':        this.hcVersion,
                'iconArraySizes':   this.iconArraySizes,
                'labels':           this.labels,
                'lastUpdate':       this.lastUpdate,
                'reference':        this.reference,
                'referenceClasses': this.referenceClasses,
                'summary':          this.summary,
                'selectedSize':     this.selectedSize,
                'selectedLayout':   this.selectedLayout,
                'language':         this.selectedLanguage,
                'title':            this.title,
                'url':              this.url
            }
        );
    }

    createFileNames() {
        let d = new Date();
        let title = this.title[this.selectedLanguage];
        let titleLength = Math.min(title.length, 10);

        title = title.substring(0, titleLength);
        let filename = d.getFullYear().toString() + (d.getMonth() + 1).toString() + d.getDate().toString() + '_';
        this.title[this.selectedLanguage] + title + '_' + this.selectedLanguage;
        this.jsonFilename = filename + '.json';
        this.svgFilename = filename + '.svg';
        this.pdfFilename = filename + '.pdf';
    }

    textareaFocused(event) {
        event.target.focus();
        setTimeout(function() { event.target.select(); }, 1);
    }

    textareaAutoResize(element) {
        // disabled
        // element.style.height = 'auto';
        // element.style.height = (element.scrollHeight) + 'px';
    }

    redrawIconArrays(fromScratch, e) {
        this.updateExportData();
    }

    // number of total samples changed
    iconArraySizeChanged(e) {
        this.selectedSize = parseInt(e.target.value);
        this.updateExportData();
    }

    addClass(idx, e) {
        if (this.classes.length < this.maxClasses) {  // limit number of classes

            let cids = this.classes.map(c => { return c.id; });  // get all class ids
            let cid = 0;
            if (cids.length !== 0) {
                cid = Math.max.apply(null, cids) + 1;  // assign new class max id + 1 = 1;
            }

            // let bfits = this.classes.filter(c => { return c.risk });
            // let col = undefined;
            // if (bfits.length + 1 < this.colours.benefits.length) {
            //     col = this.colours.benefits[bfits.length + 1];
            // } else {
            //     col = this.colours.benefits[0];
            // }

            let newClass = {
                id: cid,  // new id is id of last element + 1
                colour: undefined,
                name: { 'de': '', 'en': '' },
                comment: { 'de': '', 'en': '' },
                context: [{ 'de': '', 'en': '' }, { 'de': '', 'en': '' }],
                risk: false,
                samples: [0, 0]
            };

            this.classes.push(newClass);
            newClass.colour = this.getColour(newClass);

            this.updateExportData();
        }
    }

    removeClass(cidx, e) {
        this.classes.splice(cidx, 1);
        this.updateExportData();
    }

    addFAQ(idx, e) {

        let qids = this.faq.map(c => { return c.id; });  // get all faq ids
        let qid = 0;
        if (this.faq.length !== 0) {
            qid = Math.max.apply(null, qids) + 1;  // assign new max id + 1
        }

        let qa = {
            id: qid,
            question: { 'de': '', 'en': '' },
            answer: { 'de': '', 'en': '' },
            titlePage: false
        };
        this.faq.push(qa);
        this.updateExportData();
    }

    removeFAQ(qidx, e) {
        this.faq.splice(qidx, 1);
        this.updateExportData();
    }

    toggleRiskBenefit(cix, event) {

        let cls = this.classes[cix];
        cls.colour = this.getColour(cls);
        this.updateExportData();
    }

    getColour(cls) {
        let clss = this.classes.filter(c => { return c.risk === cls.risk; });  // risks / benefits
        let idx = clss.indexOf(cls);
        return cls.risk === false ? this.colours.benefits[idx] : this.colours.risks[idx];
    }

    // import / export
    importJSON() {
        let up = document.querySelector('#upload');

        let reader = new FileReader();
        reader.readAsText(up.files[0]);

        reader.onload = (e) => {  // I need 'this'
            let data = JSON.parse(e.target.result);
            for (let key in data) {
                this[key] = data[key];
            }

            if (this.pdfWorker) {
                this.updatePDF();
            }
            this.updateExportData();
        };
    }

    updateJSONExport() {
        this.createFileNames();

        if (this.jsonURL) {
            window.URL.revokeObjectURL(this.jsonURL);
        }

        let exportData = {
            title: this.title,
            description: this.description,
            faq: this.faq.map(function(f) {
                return {
                    id: f.id,
                    titlePage: f.titlePage,
                    question: f.question,
                    answer: f.answer
                };
            }),
            summary: this.summary,
            selectedSize: this.selectedSize,
            classes: this.classes.map(function(i) {
                return {
                    colour: i.colour,
                    name: i.name,
                    id: i.id,
                    comment: i.comment,
                    context: i.context,
                    risk: i.risk,
                    samples: i.samples
                };
            }),
            reference: this.reference,
            referenceClasses: this.referenceClasses,
            selectedLanguage: this.selectedLanguage,
            selectedLayout: this.selectedLayout,
            lastUpdate: this.lastUpdate,
            url: this.url
        };
        return new Blob([JSON.stringify(exportData)], {type: 'application/json'});
    }

    updateSVGExport() {
        let svgString = '';
        let exportData = d3.selectAll('svg');
        let serial = new XMLSerializer();

        for (let svgnode of exportData.nodes()) {
            svgString += serial.serializeToString(svgnode);
        }
        return new Blob([svgString], {type: 'application/xml'});
    }

    updateExportData(element) {

        let blob = this.updateJSONExport();
        this.jsonURL = URL.createObjectURL(blob);
        let link = document.querySelector('#exportJSON');
        link.href = this.jsonURL;

        if (this.pdfWorker) {
            this.updatePDF();
        }
    }
}
