from logging import Logger

from model.error_type import PosValidationErrorsType
from typing import Any

from interactor.route.order.add_properties.dto import AddPropertiesRequest
from model.config import Config
from model.exception import ValidationError, AuthValidationErrors
from model.order_detail import AdditionalProperty
from model.repository import PosRepositoryModel
from validation_util import \
    check_if_business_day_is_opened, \
    check_if_operator_is_logged, validate_api_key


class AddPropertiesInteractor(object):
    def __init__(self, logger, config, pos_repository):
        # type: (Logger, Config, PosRepositoryModel) -> None

        self.logger = logger
        self.config = config
        self.pos_repository = pos_repository

    def execute(self, request):
        # type: (AddPropertiesRequest) -> None

        pos_id = validate_api_key(request, self.config.api_key_mapping)

        model = self.pos_repository.get_model(pos_id)
        if not self.pos_repository.has_current_order(model):
            raise AuthValidationErrors(PosValidationErrorsType.OrderAlreadyInProgress)

        check_if_business_day_is_opened(self.pos_repository, model)
        check_if_operator_is_logged(self.pos_repository, model)

        for to_add_property in request.to_add_properties:
            self._add_property(to_add_property, pos_id, model)

    def _add_property(self, to_add_property, pos_id, model):
        # type: (AdditionalProperty, str, Any) -> None

        valid_keys = ['CUSTOMER_DOC', 'CUSTOMER_NAME', 'LOYALTY_USER_ID', 'SALE_TYPE', 'PAGER_NUMBER']

        if to_add_property.key not in valid_keys and not to_add_property.key.startswith('EXTERNAL_PROP_'):
            raise ValidationError(PosValidationErrorsType.KeyPropertyInvalid)

        pos_ot = self.pos_repository.get_pos_ot(model)

        if to_add_property.key == 'SALE_TYPE':
            if to_add_property.value not in self.config.available_sale_types:
                raise ValidationError(PosValidationErrorsType.SaleTypeInvalid)
            else:
                self.pos_repository.update_order_properties(pos_ot=pos_ot, posid=pos_id, saletype=to_add_property.value)
        else:
            self.pos_repository.add_custom_property(to_add_property.key, to_add_property.value, pos_ot)

            if to_add_property.key == "CUSTOMER_DOC":
                self.pos_repository.add_custom_property("CUSTOMER_FISCAL_DOCUMENT", to_add_property.value, pos_ot)
