import 'whatwg-fetch';

import * as d3 from './d3-custom';
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, config, lang) {

        this.controller = controller;
        this.config = config;
        this.lang = lang;

        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': config.path + 'fonts/Asap-Regular.ttf', 'data': undefined },
            'bold': { 'name': 'AsapCondensed Bold', 'url': config.path + 'fonts/Asap-Bold.ttf', 'data': undefined },
            'italic': { 'name': 'AsapCondensed Italic', 'url': config.path + 'fonts/Asap-Italic.ttf', 'data': undefined },
        };

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

        this.textWidth = 42;
        this.numColWidth = 3;

        this.offset = {
            x: 6 * this.baseFontSize,
            y: 6 * this.baseFontSize,
            selectedCaption: 3 * this.baseFontSize,
            selected: 5 * this.baseFontSize,
            similarCaption: 12 * this.baseFontSize,
            similar: 14 * this.baseFontSize,
            requirements: 23 * this.baseFontSize,
            skills: 25 * 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;
                });
        }
    }

    listUpdated(list) {
        this.drawPDF(list);
    }

    drawPDF(entry) {

        if(this.fontsloaded === 0) {
            return;
        }

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

        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

        let subject = this.config.pdf.subject[this.lang];
        // meta data
        doc.info.Title = this.config.title[this.lang];
        doc.info.Author = this.config.pdf.author;
        doc.info.Subject = subject;

        // title
        doc.fillColor('#333333')
            .font(this.fontData.bold.name)
            .fontSize(this.baseFontSize * 1.5)
            .text(this.config.title[this.lang], this.offset.x, this.offset.y, { width: 410 });

        // selected job caption
        doc.fillColor('#333333')
            .fontSize(this.baseFontSize * 1)
            .text(
                this.config.pdf.selected[this.lang],
                this.offset.x,
                this.offset.y + this.offset.selectedCaption,
                { width: 410 }
            );

        // selected job title
        doc.font(this.fontData.roman.name)
            .fontSize(this.baseFontSize * 1.5);
        doc.text(
            entry.text,
            this.offset.x,
            this.offset.selected * this.lineSpacing + this.offset.y,
            { width: this.baseFontSize * this.textWidth, align: 'center', lineBreak: false }
        );

        // similar job caption
        doc.font(this.fontData.bold.name)
            .fontSize(this.baseFontSize);
        doc.text(
            this.config.pdf.similar[this.lang],
            this.offset.x,
            this.offset.y + this.offset.similarCaption,
            { width: 410 }
        );
        // similar jobs
        doc.font(this.fontData.roman.name);

        entry.similar.forEach(function(similar, i) {
            doc.text(
                similar.entry.label,
                this.offset.x,
                (i * this.baseFontSize) * this.lineSpacing + this.offset.y + this.offset.similar,
                { width: this.baseFontSize * this.textWidth, align: 'left', lineBreak: false }
            );
            doc.text(
                (similar.entry.value * 100).toFixed(0) + '%',
                this.offset.x + this.baseFontSize * (this.textWidth - this.numColWidth),
                (i * this.baseFontSize) * this.lineSpacing + this.offset.y + this.offset.similar,
                { width: this.baseFontSize * this.numColWidth, align: 'right', lineBreak: false }
            );
        }, this);

        // requirements
        doc.font(this.fontData.bold.name);
        doc.fillColor('#333333')
            .fontSize(this.baseFontSize * 1)
            .text(this.config.pdf.requirements[this.lang], this.offset.x, this.offset.y + this.offset.requirements, { width: 410 });

        // skills
        doc.font(this.fontData.roman.name);
        entry.skills.forEach(function(skill, i) {
            doc.text(
                this.config.skills[i][this.lang],
                this.offset.x,
                (i * this.baseFontSize) * this.lineSpacing + this.offset.y + this.offset.skills,
                { width: this.baseFontSize * this.textWidth, align: 'left', lineBreak: false }
            );
            doc.text(
                skill,
                this.offset.x + this.baseFontSize * (this.textWidth - this.numColWidth),
                (i * this.baseFontSize) * this.lineSpacing + this.offset.y + this.offset.skills,
                { width: this.baseFontSize * this.numColWidth, align: 'right', lineBreak: false }
            );
        }, this);

        // 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

        doc.end();

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