import 'whatwg-fetch';

import * as d3 from './d3-custom';
import { round, typeset } from './utilities';

import * as RA_LOGO from './logos/RA_logo_1280.js';
import * as HC_LOGO from './logos/hc_logo.js';
import * as BMJV_LOGO from './logos/BMJV_logo.js';

export class PDFExport {

    constructor(controller, labels, lang) {

        this.controller = controller;
        this.labels = labels;
        this.lang = lang;
        this.entries = undefined;
        this.raLogo = RA_LOGO.default;
        this.hcLogo = HC_LOGO.default;
        this.bmjvLogo = BMJV_LOGO.default;

        this.fontcounter = 0;
        this.fontsloaded = 0;
        this.fontData = {
            'roman': { 'name': 'AsapCondensed', 'url': this.labels.path + 'fonts/Asap-Regular.ttf', 'data': undefined },
            'bold': { 'name': 'AsapCondensed Bold', 'url': this.labels.path + 'fonts/Asap-Bold.ttf', 'data': undefined },
            'italic': { 'name': 'AsapCondensed Italic', 'url': this.labels.path + 'fonts/Asap-Italic.ttf', 'data': undefined },
        };

        this.lineSpacing = 1.5;
        this.baseFontSize = 11;

        this.offset = {
            x: 4 * this.baseFontSize,
            y: 8 * this.baseFontSize
        };

        this.fontcounter = Object.keys(this.fontData).length;

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

            window.fetch(cfd.url)
                .then(response => response.arrayBuffer())
                .then(data => {
                    cfd.data = data;
                    this.fontsloaded += 1;
                    if (this.fontsloaded === Object.keys(this.fontData).length) {
                        if (this.entries !== undefined) {
                            this.drawPDF();
                        }
                    }
                });
        }
    }

    entriesListUpdated(entries) {
        this.entries = entries;
        if(this.fontsloaded < Object.keys(this.fontData).length) {  // only draw after all fonts are loaded
            return;
        }
        this.drawPDF();
    }

    hideDownloadButton(visibility) {
        this.controller.hideDownloadButton(visibility);
    }

    drawPDF() {

        if(this.entries.length < 1) {
            this.hideDownloadButton(true);
        } else {
            this.hideDownloadButton(false);
        }

        let doc = new PDFDocument(  // eslint-disable-line no-undef
            {
                size: 'A5',
                layout: 'landscape',
                margin: 0
            }
        );

        // RA LOGO
        doc.save();
        doc.transform(
            this.raLogo.transform.a11,
            this.raLogo.transform.a21,
            this.raLogo.transform.a12,
            this.raLogo.transform.a22,
            this.raLogo.transform.a13,
            this.raLogo.transform.a23
        );

        for (let i = 0; i < this.raLogo.elements.length; i += 1) {
            let el = this.raLogo.elements[i];
            doc.fillColor(el.fill);
            doc.path(el.data);
            doc.fill(el.fillRule);
        }
        doc.restore();

        // HC LOGO
        let logo = this.hcLogo.versions[this.lang];
        doc.save()
            .transform(
                logo.transform.a11,
                logo.transform.a21,
                logo.transform.a12,
                logo.transform.a22,
                logo.transform.a13,
                logo.transform.a23
            );

        for (let i = 0; i < logo.paths.length; ++i) {
            doc
                .fillColor(logo.fills[i])
                .path(logo.paths[i])
                .fill('nonzero');
        }
        doc.restore();

        // BMJV LOGO
        doc.save();
        doc.transform(
            this.bmjvLogo.transform.a11,
            this.bmjvLogo.transform.a21,
            this.bmjvLogo.transform.a12,
            this.bmjvLogo.transform.a22,
            this.bmjvLogo.transform.a13,
            this.bmjvLogo.transform.a23
        );

        for (let i = 0; i < this.bmjvLogo.elements.length; i += 1) {
            let el = this.bmjvLogo.elements[i];
            doc.fillColor(el.fill);
            doc.path(el.data);
            doc.fill(el.fillRule);
        }
        doc.restore();

        // <<< LOGOS

        for(let fd in this.fontData) {
            let cfd = this.fontData[fd];
            doc.registerFont(cfd.name, cfd.data);
        }

        this.stream = doc.pipe(blobStream());  // eslint-disable-line no-undef

        let mainGroup = this.labels.mainGroup[this.lang];
        // meta data
        let title = this.labels.title[this.lang];
        doc.info.Title = this.labels.title[this.lang];
        doc.info.Author = this.labels.pdfAuthor;
        doc.info.Subject = this.labels.title[this.lang];

        // static text
        doc
            .fillColor('#333333')
            .font(this.fontData.bold.name)
            .fontSize(this.baseFontSize * 1.563)  // major third
            .text(this.labels.title[this.lang], this.offset.x * 3, this.offset.y, { width: 410, continued: true })
            .font(this.fontData.italic.name)
            .fillColor('#888888')
            .fontSize(this.baseFontSize)
            .moveDown(0.45)
            .text('  –  binnen eines Jahres');

        doc.fontSize(this.baseFontSize * 1)
            .fillColor('#888888')
            .font(this.fontData.italic.name)
            .text(this.labels.of[this.lang] + ' 100 000', this.offset.x, this.offset.y + 3 * this.baseFontSize, { width: 80, align: 'right' })
            .text(mainGroup, this.offset.x * 3, this.offset.y + 3 * this.baseFontSize, { width: 100, align: 'left' });

        doc.fillColor('#333333')
            .font(this.fontData.roman.name);

        // dynamic text: entries
        this.entries.forEach(function(entry, i) {
            // entry value
            doc.font(this.fontData.roman.name)
                .text(
                    typeset(round(entry.value), this.lang),
                    this.offset.x,
                    (i + 3) * this.baseFontSize * this.lineSpacing + this.offset.y,
                    { width: 80, align: 'right', lineBreak: false }
                );
            // entry reference group
            doc.font(this.fontData.italic.name)
                .text(
                    entry.reason.referenceGroup + ': ',
                    this.offset.x * 3,
                    (i + 3) * this.baseFontSize * this.lineSpacing + this.offset.y,
                    { width: 400, align: 'left', continued: true }
                );
            // entry title
            doc.font(this.fontData.roman.name)
                .text(
                    entry.reason.title,
                    this.offset.x * 3,
                    (i + 3) * this.baseFontSize * this.lineSpacing + this.offset.y
                );
        }, this);

        doc.end();

        this.stream.on('finish', function() {
            let link = d3.select('#exportPDF').node();
            let url = this.toBlobURL('application/pdf');
            link.href = url;
            link.download = title + '.pdf';
        });
    }
}
