# -*- coding: utf-8 -*-

import json

from sysactions import (
    action,
    show_messagebox,
    close_asynch_dialog,
)

from typing import Callable
from utilfunctions import compare_objects

from ..customer import Customer
from ..customer.customer_model import AddCustomerRequest

dialog_id = None


def insert_or_update_customer_with_confirmation(
    pos_id,                # type: str
    customer_json,         # type: dict
):
    # type: (...) -> bool

    def confirmation_callback(callback_action):
        if callback_action == "INSERT":
            message = "$CUSTOMER_WILL_BE_INSERTED"
        else:
            message = "$CUSTOMER_WILL_BE_UPDATED"

        confirmation = show_messagebox(
            posid=pos_id,
            message=message,
            timeout=720000,
            buttons="$OK|$CANCEL",
        )
        return confirmation != 1

    return insert_or_update_customer(
        customer_json=customer_json,
        confirmation_callback=confirmation_callback,
    )


def insert_or_update_customer(
    customer_json,                  # type: dict
    confirmation_callback=None,     # type: Callable[[str], bool]
):
    # type: (...) -> bool

    customer_request = _create_customer_request(customer_json)

    customer = Customer().get_customer(phone=customer_request.phone)
    if not customer:
        if confirmation_callback is not None and not confirmation_callback("INSERT"):
            return False
        Customer().add_customer(add_customer_request=customer_request)
    else:
        same_customer = compare_objects(
            obj1=customer_request,
            obj2=_create_customer_request_to_compare(customer=json.loads(customer)),
        )
        if not same_customer and confirmation_callback is not None and not confirmation_callback("UPDATE"):
            return False
        Customer().update_customer(add_customer_request=customer_request)

    return True


def _create_customer_request(address_data_load):
    add_customer_request = AddCustomerRequest(
        address_data_load["CUSTOMER_PHONE"],
        address_data_load["CUSTOMER_DOC"],
        address_data_load["CUSTOMER_NAME"],
        address_data_load["POSTAL_CODE"],
        address_data_load["STATE"],
        address_data_load["CITY"],
        address_data_load["STREET_NAME"],
        address_data_load["NEIGHBORHOOD"],
        address_data_load["STREET_NUMBER"],
        address_data_load["COMPLEMENT"],
        address_data_load["ADDRESS_REFERENCE"]
    )

    return add_customer_request


def _create_customer_request_to_compare(customer):
    add_customer_request = AddCustomerRequest(
        customer["phone"],
        customer["document"],
        customer["name"],
        customer["address"]["zip_code"],
        customer["address"]["state"],
        customer["address"]["city"],
        customer["address"]["street"],
        customer["address"]["neighborhood"],
        customer["address"]["number"],
        customer["address"]["complement"],
        customer["address"]["reference_point"]
    )
    return add_customer_request


@action
def zip_code_search(pos_id):
    global dialog_id
    dialog_id = show_messagebox(pos_id, "$SEARCHING_ZIP_CODE", buttons="", asynch=True, timeout=50000)


@action
def zip_code_search_finished(pos_id, error="false"):
    close_asynch_dialog(pos_id, dialog_id)
    if error == "true":
        show_messagebox(pos_id, "$ERROR_SEARCHING_ZIP_CODE", buttons="OK")
