from abc import ABCMeta, abstractmethod
from xml.etree import cElementTree as eTree

from posot import OrderTaker

from typing import Optional, Any, List


class PosRepositoryModel(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def get_model(self, pos_id):
        # type: (int) -> eTree

        raise NotImplementedError

    @abstractmethod
    def get_pos_ot(self, model):
        # type: (eTree) -> Any

        raise NotImplementedError

    @abstractmethod
    def get_price_list(self, model):
        # type: (eTree) -> str

        raise NotImplementedError

    @abstractmethod
    def is_day_opened(self, model):
        # type: (eTree) -> bool

        raise NotImplementedError

    @abstractmethod
    def is_day_blocked(self, model):
        # type: (eTree) -> bool

        raise NotImplementedError

    @abstractmethod
    def translate_message(
        self,
        model,      # type: eTree
        message,    # type: str
    ):
        # type: (...) -> str

        raise NotImplementedError

    @abstractmethod
    def is_operator_logged(self, model):
        # type: (eTree) -> bool

        raise NotImplementedError

    @abstractmethod
    def has_operator_opened(self, model):
        # type: (eTree) -> bool

        raise NotImplementedError

    @abstractmethod
    def get_current_operator(self, model):
        # type: (eTree) -> Optional[eTree]

        raise NotImplementedError

    @abstractmethod
    def has_current_order(self, model):
        # type: (eTree) -> bool

        raise NotImplementedError

    @abstractmethod
    def is_order_in_progress(self, model):
        # type: (eTree) -> bool

        raise NotImplementedError

    @abstractmethod
    def is_order_totaled(
        self,
        model,                  # type: eTree
        order_picture=None,     # type: Optional[eTree]
    ):
        # type: (...) -> bool

        raise NotImplementedError

    @abstractmethod
    def get_current_order(self, model):
        # type: (eTree) -> Optional[eTree]

        raise NotImplementedError

    @abstractmethod
    def create_order(self, pos_id, pos_ot, price_list=None, sale_type=None):
        # type: (int, Any, Optional[str], Optional[str]) -> int

        raise NotImplementedError

    @abstractmethod
    def get_order_details(self, pos_id, order_id, pos_ot):
        # type: (int, int, Any) -> eTree

        raise NotImplementedError

    @abstractmethod
    def get_order_picture(
        self,
        pos_id,         # type: str
        order_id,       # type: str
        model,          # type: eTree
        pos_ot=None,    # type: Optional[OrderTaker]
    ):
        # type: (...) -> eTree

        raise NotImplementedError

    @abstractmethod
    def add_item_to_order(
        self,
        pos_id,          # type: int
        pos_ot,          # type: Any
        price_list,      # type: str
        model,           # type: eTree
        item,            # type: Any
        sale_type=None   # type: Optional[str]
    ):
        # type: (...) -> None

        raise NotImplementedError

    @abstractmethod
    def reopen_shopping_cart(
            self,
            pos_id,     # type: int
            pos_ot      # type: Any
    ):
        # type: (...) -> int

        raise NotImplementedError

    @abstractmethod
    def order_has_tender(self, model):
        # type: (eTree) -> Optional[eTree]

        raise NotImplementedError

    def void_order(
        self,
        pos_id,         # type: int
        pos_ot,         # type: OrderTaker
        order_id="",    # type: Optional[str]
    ):
        # type: (...) -> None

        raise NotImplementedError

    def delete_line(self, pos_id, pos_ot, line_numbers):
        # type: (int, Any, List[int]) -> None

        raise NotImplementedError

    @abstractmethod
    def get_pos_list(self):
        # type: () -> tuple

        raise NotImplementedError

    @abstractmethod
    def do_tender(self, pos_id, tender_id, pos_ot, amount):
        # type: (int, int, Any, float) -> Any

        raise NotImplementedError

    def do_clear_tender(
            self,
            pos_id,      # type: str
            model,       # type: object
            tender_id    # type: int
    ):
        # type: (...) -> Any

        raise NotImplementedError

    @abstractmethod
    def add_custom_property(self, key, value, pos_ot):
        # type: (str, str, Any) -> None

        raise NotImplementedError

    @abstractmethod
    def add_custom_properties(self,  pos_ot, properties, orderid=''):
        # type: (Any, dict, str) -> None

        raise NotImplementedError

    @abstractmethod
    def update_order_properties(self, pos_ot, posid, saletype):
        # type: (Any, str, str) -> eTree

        raise NotImplementedError

    @abstractmethod
    def do_total(self, pos_id, pos_ot):
        # type: (int, Any) -> eTree

        raise NotImplementedError

    @abstractmethod
    def get_rupture_products(self):
        # type: () -> list

        raise NotImplementedError

    @abstractmethod
    def get_menu_data(self):
        # type: () -> bytearray

        raise NotImplementedError

    @abstractmethod
    def get_nf_type(self):
        # type: () -> bool

        raise NotImplementedError

    @abstractmethod
    def get_sefaz_status(self):
        # type: () -> bool

        raise NotImplementedError

    @abstractmethod
    def get_store_sat_status(
        self,
    ):
        # type: (...) -> bool

        raise NotImplementedError

    @abstractmethod
    def get_catalog_version(self):
        # type: () -> str

        raise NotImplementedError

    @abstractmethod
    def set_order_to_paid(
        self,
        pos_id,     # type: str
        order_id,   # type: str
        model,      # type: eTree
        pos_ot,     # type: OrderTaker
    ):
        # type: (...) -> Any

        raise NotImplementedError

    @abstractmethod
    def void_tenders_and_order(self, model, pos_ot):
        # type: (eTree, object) -> Any

        raise NotImplementedError

    @abstractmethod
    def logout_delivery_user(self, pos_id, operator_id):
        # type: (int, str) -> bool

        raise NotImplementedError

    @abstractmethod
    def close_business_period(self, pos_id):
        # type: (int) -> bool

        raise NotImplementedError

    @abstractmethod
    def open_business_period(self, pos_id):
        # type: (int) -> bool

        raise NotImplementedError

    @abstractmethod
    def authenticate_user(self, user_id, user_password):
        # type: (str, str) -> Any

        raise NotImplementedError

    @abstractmethod
    def open_user(self, pos_id, user_id, long_user_name):
        # type: (int, str, str) -> bool

        raise NotImplementedError

    @abstractmethod
    def login_user(self, pos_id, user_id, long_user_name):

        raise NotImplementedError

    @abstractmethod
    def get_read_scanner(self, pos_id):

        raise NotImplementedError

    @abstractmethod
    def print_text(self, pos_id, content):
        # type: (str, str) -> bool

        raise NotImplementedError

    @abstractmethod
    def get_storewide_config(self, parameter, defval, array):
        # type: (str, Optional[bool], Optional[bool]) -> list

        raise NotImplementedError

    @abstractmethod
    def apply_coupon(self, pos_id, coupon_code):
        # type: (int, str) -> (str, bool)

        raise NotImplementedError

    @abstractmethod
    def get_order_custom_properties(self, pos_ot, key, order_id=""):
        # type: (Any, str, int) -> eTree

        raise NotImplementedError

    @abstractmethod
    def get_cfg(self, pos_id, key, default):
        # type: (int, str, str) -> Any

        raise NotImplementedError

    @abstractmethod
    def change_line_quantity(self, model, pos_ot, to_change_items):
        # type: (eTree.Element, object, List) -> Any

        raise NotImplementedError

    @abstractmethod
    def remove_coupon(
            self,
            pos_id,         # type: int
            coupon_code     # type: str
    ):
        # type: (...) -> Any

        raise NotImplementedError

    @abstractmethod
    def get_text_from_i18n(self):
        # type: () -> Any

        raise NotImplementedError

    @abstractmethod
    def get_static_config(
        self,
        pos_id  # type: str
    ):
        # type: (...) -> Any

        raise NotImplementedError

    @abstractmethod
    def get_tender_types(self):
        # type: () -> Any

        raise NotImplementedError

    @abstractmethod
    def get_navigation(
            self,
            pos_id  # type: int
    ):
        # type: (...) -> Any

        raise NotImplementedError

    def do_stored_order(
        self,
        pos_id,     # type: int
        model,      # type: eTree
    ):
        # type: (...) -> None

        raise NotImplementedError

    @abstractmethod
    def get_manager_status(
        self,
        pos_id,     # type: int
    ):
        # type: (...) -> Any

        raise NotImplementedError
