from flask import current_app
from .ligne_model import Ligne
from time import sleep
import six


class Ticket:
    def __init__(self):
        self.titre = ""
        self.titre_style = {}
        self.date = ""
        self.date_style = {}
        self.imprimante = ""
        self.imprimante_style = {}
        self.type = ""
        self.type_style = {}
        self.caissier = ""
        self.caissier_style = {}
        self.imprimanteId = 0
        self.lalivraison = ""
        self.lalivraison_style = {}
        self.client = ""
        self.client_style = {}
        self.texte = ""
        self.texte_style = {}
        self.lignes = []
        pass

    def from_json(self, jsonObject):
        """
        Extraire les attributs du jsonObject.

        Exemple de json attendu :
        {
            "titre":123456,
            "titre_style": {},
            "date": "26/03/2021 09:01:34",
            "date_style": {},
            "imprimante": "",
            "imprimante_style": {},
            "type": "Sur Place",
            "type_style": {},
            "caissier": "Hamid",
            "caissier_style": {},
            "imprimanteId": 1,
            "lalivraison" : "123456",
            "lalivraison_style": {},
            "client" : "0612345678, adresse, ...",
            "client_style": {},
            "texte": "Un Texte",
            "texte_style": {},
            "lignes": [
                {
                    "designation": "Plat XXXXXXX",
                    "qte": 1,
                    "note": "Sans quelque chose",
                    "style": {}
                },
                {
                    "designation": "Formule XXXXXXX",
                    "qte": 2,
                    "style": {},
                    "formule": [
                        {
                            "designation": "Plat XXXXXXX",
                            "qte": 1,
                            "note": "Sans quelque chose",
                            "style": {}
                        },
                        {
                            "designation": "Plat XXXXXXX",
                            "qte": 1,
                            "note": "Sans quelque chose",
                            "style": {}
                        }
                    ]
                }
            ]
        }

        Attributs Style :
        {
            "align":"center" | "left" | "right",
            "font":"a" | "b",
            "width": 1-8,
            "height":1-8,
            "invert":0-1,
            "text_type":"B" | "U" | "BU"
        }
        """

        self.titre = self.parse_text(jsonObject.get("titre"))
        self.titre_style = self.parse_style(jsonObject.get("titre_style"))
        self.date = self.parse_text(jsonObject.get("date"))
        self.date_style = self.parse_style(jsonObject.get("date_style"))
        self.imprimante = self.parse_text(jsonObject.get("imprimante"))
        self.imprimante_style = self.parse_style(jsonObject.get("imprimante_style"))
        self.type = self.parse_text(jsonObject.get("type"))
        self.type_style = self.parse_style(jsonObject.get("type_style"))
        self.caissier = self.parse_text(jsonObject.get("caissier"))
        self.caissier_style = self.parse_style(jsonObject.get("caissier_style"))
        self.imprimanteId = self.parse_text(jsonObject.get("imprimanteId"))
        self.lalivraison = self.parse_text(jsonObject.get("lalivraison"))
        self.lalivraison_style = self.parse_style(jsonObject.get("lalivraison_style"))
        self.client = self.parse_text(jsonObject.get("client"))
        self.client_style = self.parse_style(jsonObject.get("client_style"))
        self.texte = self.parse_text(jsonObject.get("texte"))
        self.texte_style = self.parse_style(jsonObject.get("texte_style"))

        if "lignes" in jsonObject:
            if isinstance(jsonObject.get("lignes"), list):
                for item in jsonObject.get("lignes"):
                    line = Ligne()
                    line.from_json(item)
                    self.lignes.append(line)

    def to_str(self):
        out = "" + "\n"
        out += str(self.titre) + "\n"
        out += str(self.date) + "\n"
        out += str(self.imprimante) + "\n"
        out += str(self.type) + "\n"
        out += str(self.caissier) + "\n"
        out += str(self.imprimanteId) + "\n"
        if self.lalivraison:
            out += str(self.lalivraison) + "\n"
        if self.client:
            out += str(self.client) + "\n"
        out += str(self.texte) + "\n"

        if self.lignes:
            out += str("-" * 48) + "\n"
            out += "QTE | ARTICLE" + "\n"
            out += str("-" * 48) + "\n"

            for line in self.lignes:
                out += (
                    "%2s%s%s" % (str(line.qte)[:2], " " * 2, str(line.designation))
                    + "\n"
                )
                out += (
                    "%s%s" % (" " * 4, str(line.note)) + "\n" if line.note else ""
                )
                for line_formule in line.formule:
                    out += (
                        "%s%2s%s%s"
                        % (
                            " " * 2,
                            str(line_formule.qte)[:2],
                            " " * 2,
                            str(line_formule.designation)[:42],
                        )
                        + "\n"
                    )
                    out += (
                        "%s%s" % (" " * 6, str(line_formule.note)[:42]) + "\n"
                        if line_formule.note
                        else ""
                    )

        return out

    def to_printer(self, printer):
        printer._raw(b"\x1b" + b"\x42" + six.int2byte(2) + six.int2byte(1))
        sleep(1)
        printer.set(**self.titre_style)
        printer.text(str(self.titre) + "\n")
        printer.set(**self.date_style)
        printer.text(str(self.date) + "\n")
        printer.set(**self.imprimante_style)
        printer.text(str(self.imprimante) + "\n")
        printer.set(**self.type_style)
        printer.text(str(self.type) + "\n")
        printer.set(**self.caissier_style)
        printer.text(str(self.caissier) + "\n")
        printer.set()
        printer.text("ImprimanteId : " + str(self.imprimanteId) + "\n")
        if self.lalivraison:
            printer.set(**self.lalivraison_style)
            printer.text(str(self.lalivraison) + "\n")
        if self.client:
            printer.set(**self.client_style)
            printer.text(str(self.client) + "\n")
        printer.set(**self.texte_style)
        printer.text(str(self.texte) + "\n")

        if self.lignes:
            printer.set(text_type="B")
            printer.text(str("-" * 48) + "\n")
            printer.text("QTE | ARTICLE" + "\n")
            printer.text(str("-" * 48) + "\n")
            printer.set()

            for line in self.lignes:
                printer.set(**self.parse_style(line.style))
                printer.text(
                    "%2s%s%s" % (str(line.qte)[:2], " " * 2, str(line.designation))
                    + "\n"
                )

                if line.note:
                    printer.set()
                    printer.text("%s%s" % (" " * 4, str(line.note)[:44]) + "\n")

                printer.set()
                printer.text("\n")

                for line_formule in line.formule:
                    printer.set(**self.parse_style(line_formule.style))
                    printer.text(
                        "%s%4s%s%s"
                        % (
                            " " * 2,
                            str(line_formule.qte)[:2],
                            " " * 2,
                            str(line_formule.designation)[:42],
                        )
                        + "\n"
                    )
                    if line_formule.note:
                        printer.set()
                        printer.text(
                            "%s%s" % (" " * 6, str(line_formule.note)[:42]) + "\n"
                        )

                    printer.set()
                    printer.text("\n")

        printer.set()
        printer.cut()
        printer._raw(b"\x1b" + b"\x42" + six.int2byte(2) + six.int2byte(2))
        sleep(current_app.config["TICKET_TIMEOUT"])

    def parse_text(self, text_json):
        text = ""
        if text_json:
            text = text_json

        return text

    def parse_style(self, style_json):
        """
        set(align="center", font="a",width=2, height=2, invert=True, text_type="B")
        """
        styles = {}

        if style_json == None:
            return styles

        if "align" in style_json:
            if style_json["align"] in ("center", "left", "right"):
                styles["align"] = style_json["align"]

        if "font" in style_json:
            if style_json["font"] in ("a", "b"):
                styles["font"] = style_json["font"]

        if "width" in style_json:
            width = int(style_json["width"])
            if width >= 1 and width <= 8:
                styles["width"] = width

        if "height" in style_json:
            height = int(style_json["height"])
            if height >= 1 and width <= 8:
                styles["height"] = height

        if "invert" in style_json:
            invert = int(style_json["invert"])
            styles["invert"] = bool(invert)

        if "text_type" in style_json:
            if style_json["text_type"] in ("B", "U", "BU"):
                styles["text_type"] = style_json["text_type"]

        return styles
