from escposformatter import DefaultEscPosFormatter
from htmlformatter import HtmlFormatter
from report import (
    ReportParser,
    Report,
)
from sysactions import (
    generate_report,
    print_text,
    show_print_preview,
    show_messagebox,
)

from typing import (
    Any,
    Optional,
    Union,
)
from xml.etree import cElementTree as eTree

from enum import Enum

from utilfunctions import (
    get_device_service,
    get_sector_name,
)


class PrinterType(Enum):
    esc_pos = "ESC_POS"
    apos = "APOS"


def print_report(
    pos_id,               # type: Any[Union[str, int]]
    report_name,          # type: str
    report_args,          # type: list
    preview=True,         # type: Optional[bool]
    order=None,           # type: Optional[eTree]
    allow_printing=True,  # type: Optional[bool]
    allow_accents=False,  # type: Optional[bool]
    is_mobile=False,      # type: Optional[bool]
):
    # type: (...) -> Optional[bool]

    report_data = generate_report(
        report_name,
        pos_id,
        *report_args
    )
    report = ReportParser().parse(report=report_data)

    current_printer = _get_printer(
        pos_id=pos_id,
        order=order,
    )

    if report is not None:
        if preview:
            print_preview_report = HtmlFormatter().format(report)
            result = show_print_preview(
                posid=pos_id,
                text_data=print_preview_report.encode("utf-8"),
                title="$PRINT_PREVIEW",
                buttons="$PRINT|$CLOSE" if allow_printing else "$CLOSE",
            )
            if result in (1, None) or not allow_printing:
                return False

        print_data = _get_print_data(
            report=report,
            is_mobile=is_mobile,
            allow_accents=allow_accents,
        )

        print_text(
            posid=pos_id,
            model=None,
            text=print_data,
            force_printer=current_printer,
        )
    else:
        show_messagebox(
            posid=pos_id,
            title="$NO_REPORT_DATA",
            message="$ERROR",
        )


def _get_print_data(
    report,         # type: Report
    is_mobile,      # type: bool
    allow_accents,  # type: bool
):
    # type: (...) -> str

    if is_mobile:
        return DefaultEscPosFormatter().format_mobile(
            report=report,
        )

    return DefaultEscPosFormatter().format(
        report=report,
        allow_accents=allow_accents,
    )


def _get_printer(
    pos_id,         # type: Any[Union[str, int]]
    order=None,     # type: Optional[eTree]
):
    # type: (...) -> str

    sector_name = get_sector_name(order=order) if order else None
    current_printer = get_device_service(
        pos_id=pos_id,
        device_type="printer",
        sector=sector_name,
    )
    return current_printer
