from typing import Dict
from typing import Optional


def compose_custom_response(
    resp: Dict,
    success_message: str = "Operation successful.",
    fail_message: str = "Operation failed.",
) -> Dict:
    """Enhances a dictionarised Misty2pyResponse with `success_message` in case of success and with `fail_message` otherwise.

    Args:
        resp (Dict): The dictionarised Misty2pyResponse.
        success_message (str, optional): A message/keyword to append in case of success. Defaults to `"Operation successful."`.
        fail_message (str, optional): A message/keyword to append in case of failure. Defaults to `"Operation failed."`.

    Returns:
        Dict: The enhanced version.
    """

    def compose_str(
        main_str: str, potential_str: Optional[str], fallback: Optional[str] = None
    ) -> str:
        """Composes a single string from main_str, potential_str and fallback.
        - If `potential_str` and `fallback` are both `None`, the final string is `main_str`.
        - If `potential_str` is a string, the final string is `main_str` followed by a space and `potential_str`.
        - If `potential_str` is `None` and `fallback` is a string, the final string is `main_str` followed by a space and `fallback`.
        """
        if isinstance(potential_str, str):
            return "%s %s" % (main_str, potential_str)
        if isinstance(fallback, str):
            return "%s %s" % (main_str, fallback)
        return main_str

    success = resp.get("overall_success")
    dct = {"overall_success": success}
    potential_resp = resp.get("rest_response")

    if potential_resp:
        potential_message = potential_resp.get("message")

        if success:
            message = compose_str(success_message, potential_message)
        else:
            message = compose_str(
                fail_message, potential_message, fallback="No further details provided."
            )
        dct["rest_response"] = {
            "success": potential_resp.get("success"),
            "message": message,
        }

    return dct