import { Injectable } from "@angular/core";
import { NotifyService } from "./notify.service";

declare let qz: any;

@Injectable()
export class PrintService {

    printer: any;
    printerName: any;

    isDotMatrixPrinting: boolean;
    dotMatrixStatus: string;

    constructor(private readonly notifyService: NotifyService) { }

    getPrinterName = () => {
        return localStorage.getItem("DotMatrixPrinterName");
    }

    setPrinterName = (name: string) => {
        localStorage.setItem("DotMatrixPrinterName", name);
        this.printerName = localStorage.getItem("DotMatrixPrinterName");
    }

    getPrinters = (callback?: Function) => {
        qz.printers.find().then((data: Array<any>) => {
            callback(data);
        }).catch((e) => {
            callback(new Array<any>());
            this.notifyService.warning(e);
        });
    }

    getAvailablePrinters = (callback?: Function) => {
        if (!qz.websocket.isActive()) {
            qz.websocket.connect().then(() => {
                this.getPrinters(callback);
            }).catch((e) => {
                this.notifyService.warning(e);
            });
        } else {
            this.getPrinters(callback);
        }
    }

    private findPrinter(callback?: Function) {

        this.printerName = this.getPrinterName();
        if (!this.printerName) {
            this.notifyService.warning("Please select printer.");
            callback();
        }

        qz.printers.find(this.printerName).then((data) => {
            this.printer = data;
            this.dotMatrixStatus = "Connected";
            callback();
        }).catch((e) => {
            this.notifyService.warning(e);
            this.isDotMatrixPrinting = false;
        });
    }

    private connect(callback?: Function) {
        this.dotMatrixStatus = "Connecting...";
        qz.websocket.connect().then(() => {
            this.findPrinter(() => {
                callback();
            });
        }).catch((e) => {
            this.notifyService.warning(e);
            this.isDotMatrixPrinting = false;
        });
    }

    private print(htmlToRender: any, configObj: any, callback?: Function) {
        this.dotMatrixStatus = "Printing...";

        const data = [{
            type: 'pixel',
            format: 'html',
            flavor: 'plain',
            data: htmlToRender
        }];

        const config = qz.configs.create(null, configObj);
        if (!this.printer) {
            this.findPrinter(() => {
                config.setPrinter(this.printer);
                qz.print(config, data).then(() => {
                    this.dotMatrixStatus = "Printed";
                    this.isDotMatrixPrinting = false;
                    callback();
                }).catch((e) => {
                    this.notifyService.warning(e);
                    this.isDotMatrixPrinting = false;
                });
            });
        } else {
            config.setPrinter(this.printer);
            qz.print(config, data).then(() => {
                this.dotMatrixStatus = "Printed";
                this.isDotMatrixPrinting = false;
                callback();
            }).catch((e) => {
                this.notifyService.warning(e);
                this.isDotMatrixPrinting = false;
            });
        }
    }

    start = (htmlToRender: any, config: any, callback?: Function) => {
        this.dotMatrixStatus = "checking...";
        this.isDotMatrixPrinting = true;
        try {
            if (!qz.websocket.isActive()) {
                this.connect(() => {
                    this.print(htmlToRender,
                        config,
                        () => {
                            this.isDotMatrixPrinting = false;
                            callback();
                        });
                });
            } else {
                this.print(htmlToRender,
                    () => {
                        this.isDotMatrixPrinting = false;
                        callback();
                    });
            }
        } catch (e) {
            this.notifyService.warning(e);
            this.isDotMatrixPrinting = false;
        }
    }

    disconnect = () => {
        if (qz.websocket.isActive()) {
            qz.websocket.disconnect();
        }
    }
}
