'''
- The ChatTree simulates the TMC platform for booking, changing and canceling air tickets, hotels and trains.
- Among them, the most complex air ticket booking business is mainly implemented through the sub ChatTree "TMC_book_flights.py". This file is mainly based on the node first_question_node modified with the "topic" infoitem modifier to complete the division of specific business and handle it separately.
- The rest of the business has only been briefly handled.
- At the same time, during the entire process, the system can provide relevant knowledge of the "TMC_product_booking_cancellation_change_and_booking_rules_instructions" knowledge base and information of the "dynamic_reference_information" defined in the "#start#" node at any time based on the user's input, and provide feedback based on the "respond_script" in the "#start#" node, without interrupting the logic of the dialogue process.
- Finally, you can execute "python ./ichatdef/firstapp/py_chattree/TMC.py" in the server's project directory to generate "TMC.html", download it locally and open it with a browser, you can see the topology structure of the entire ChatTree and related code information
'''

# -------------------------------------------------------------------------------------
# Standard code header for every python ChatTree file
# -------------------------------------------------------------------------------------

import sys, os

project_root = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../.."))
if project_root not in sys.path:
    sys.path.append(project_root)
from chattree_def import *

chattree = ChatTree()

# -------------------------------------------------------------------------------------
# The definition part of the ChatTree node
# -------------------------------------------------------------------------------------

# start node
def get_points(ctx):
    return "The user currently has a total of 1500 points"
start_node = chattree.create_node( "#start#", {
    "chattree_title":"Travel Management Company (TMC) platform services",  # A short text describing the topic or purpose of this ChatTree
    "system_role":"Travel Management Company (TMC) platform customer service staff",
    "user_role":"Travel Management Company (TMC) platform customers",
    "background_information":
        "The Travel Management Company (TMC) platform is an e-commerce platform that provides customers with hotel, air ticket, and train ticket booking services. As a TMC customer service staff, you need to efficiently solve users' travel reservations, changes, policy consultation and itinerary management issues, while ensuring compliance with corporate travel policies, improve user experience and reduce manual customer service intervention; "
        "At the same time, you need: professional and capable (answers are concise and clear, not sloppy, and reflect business attributes), polite and enthusiastic (use honorifics, remain patient, and show service awareness), objective and accurate (must be rigorous when it comes to prices and cancellation rules, and do not provide ambiguous information), empathy (when users encounter anxious situations such as flight delays, cancellations, etc., first appease their emotions and then provide solutions)",
    "allow_transfer_human_agent":True,
    "startup_infoitem":"{user_ID}",
    "static_reference_information":"TMC_product_booking_cancellation_change_and_booking_rules_instructions", # Point to the knowledge base file name (without extension)
    "dynamic_reference_information":[     # Compared with static reference information (knowledge base), dynamic reference information is text information generated by dynamically calling the corresponding function when the user input matches the relevant intention.
        { "intent":"want to know how many points currently have", "function":get_points},
        { "intent":"want to know how many membership miles currently have", "function":lambda ctx: (
            "The user's current membership mileage is 32,000 kilometers"
            if ctx["{business_the_user_wants_to_handle}"].as_str() in ["book flights", "change flights", "cancel flights"] else
            "The user's current membership mileage is 32,000 kilometers (only the ticket business involves member miles)"
        )},
    ],
    "response_scripts":[                    # When the user's input matches the corresponding intention, the system will provide feedback based on the vocabulary defined here. Note that the intentions and vocabulary here are only examples, and you can adjust and supplement them according to the actual situation.
        { "intent":"Ask for own user ID", "response":"<Tell the user that his/her user ID is {user_ID}>" }, # Note that the words "response" here are enclosed in greater than and less signs, indicating that this is a "prompt word", and the system will dynamically replace "{user_ID}" with the corresponding value in ctx
        { "intent":"Complain or question that the related change or cancellation fee is too high", "response":"I understand your feelings very much. It is really hard to accept seeing so much money being deducted. However, I need to explain to you that as a booking service provider, this platform will strictly synchronize all cancellation and change fees with the underlying systems of airlines/railway bureaus/hotels. Our platform will not charge any additional refund or change fees."},
        { "intent":"Question the difference between half-price air tickets for children and full-price air tickets for adults. In fact, the half-price air tickets for children are even higher.", "response":"<Explain to user based on the situation: ℹ️t is true that sometimes there is not much difference between the price of children's tickets and the prices of adult tickets. This is mainly because the pricing strategies of each airline are different. Although children's tickets are charged at half of the full price, the discount for adult tickets is greater in the off-season, so sometimes the price of children's tickets is higher than that of adults. This situation is relatively common in the industry>"},
        { "intent":"Request that the cabin seats of several tickets be next to each other", "response":"You can check in with several people on the mobile app and select adjacent seats. The system will try to arrange them together, but the final seat arrangement is subject to the actual situation of the airline system. Tickets can be issued and paid as soon as possible, and then check-in as early as possible"},
    ],
})

# "#single_turn_interact#" node as the topic
first_question_node = chattree.create_node( "#single_turn_interact#", {
    "infoitem": "{business_the_user_wants_to_handle}",
    "infoitem_modifier": ["topic","required"], # Note that there is a "topic" modifier
    "system_question": "What business do you need to handle?",
    "question_modifier": ["never_ask_repeatedly"],
})

# Intent branch: book flights
book_flight_ticket_intent_node = chattree.create_node( "#user_intent#", {
    "intent":"book flights",
    "re_enter_intent":"Rebook another flight",
    "re_enter_intent_constraint":"Changing the starting point or destination or airline does not count",
})

# Call the sub ChatTree "TMC_book_flights"
call_book_flight_ticket_sub_tree_node = chattree.create_node( "#activity#call_sub_tree", {
    "sub_tree":"TMC_book_flights", # filename of the sub ChatTree, without extension
})

# Intent branch: change flights
change_flight_ticket_intent_node = chattree.create_node( "#user_intent#", {
    "intent":"change flights",
    "re_enter_intent":"Rechange another flight"
})

# Inquire about specific needs for changing flights (excample)
get_change_flight_ticket_requirement_node = chattree.create_node( "#single_turn_interact#", {
    "infoitem": "{specific_requirements_for_changing_flight}",
    "infoitem_modifier": ["required"],
    "system_question": "What are your specific needs for changing your flight?",
})

# Prompt that the request to change the flight has been received (example)
inform_user_after_get_change_flight_ticket_requirement_node = chattree.create_node( "#inform_user#", {
    "inform_content": "Your flight change request has been received",
})

# Intent branch: cancel flights
cancel_flight_ticket_intent_node = chattree.create_node( "#user_intent#", {
    "intent":"cancel flights",
    "intent_constraint":"cancellations during the booking process are not counted", # Pay attention to this constraint
    "re_enter_intent":"Recancel another flight"
})

# Ask about specific needs for canceling flight (example)
get_cancel_flight_ticket_requirement_node = chattree.create_node( "#single_turn_interact#", {
    "infoitem": "{specific_requirements_for_cancelling_flight}",
    "infoitem_modifier": ["required"],
    "system_question": "What are your specific needs for cancelling your flight?",
})

# Prompt that the request to cancel the flight has been received (example)
inform_user_after_get_cancel_flight_ticket_requirement_node = chattree.create_node( "#inform_user#", {
    "inform_content": "Your flight cancel request has been received",
})

# Intent branch: Book train tickets
book_train_ticket_intent_node = chattree.create_node( "#user_intent#", {
    "intent":"Book train tickets",
    "re_enter_intent":"Rebook another train ticket"
})

# Ask about specific needs for booking train tickets (example)
get_book_train_ticket_requirement_node = chattree.create_node( "#single_turn_interact#", {
    "infoitem": "{specific_requirements_for_booking_train_tickets}",
    "infoitem_modifier": ["required"],
    "system_question": "What are your specific needs for booking train tickets?",
})

# Prompt that the demand for booking train tickets has been received (example)
inform_user_after_get_book_train_ticket_requirement_node = chattree.create_node( "#inform_user#", {
    "inform_content": "Your request for booking train tickets has been received",
})

# Intent branch: Change train tickets
change_train_ticket_intent_node = chattree.create_node( "#user_intent#", {
    "intent":"Change train tickets",
    "re_enter_intent":"Rechange another train ticket"
})

# Ask about specific needs for changing train tickets (example)
get_change_train_ticket_requirement_node = chattree.create_node( "#single_turn_interact#", {
    "infoitem": "{specific_requirements_for_changing_train_tickets}",
    "infoitem_modifier": ["required"],
    "system_question": "What are your specific needs for changing your train ticket?",
})

# Prompt that the request to change the train ticket has been received (example)
inform_user_after_change_train_ticket_requirement_node = chattree.create_node( "#inform_user#", {
    "inform_content": "Your request to change your train ticket has been received",
})

# Intent branch: Unsubscribe train tickets
cancel_train_ticket_intent_node = chattree.create_node( "#user_intent#", {
    "intent":"Unsubscribe train tickets",
    "re_enter_intent":"Re-unsubscribe another train ticket"
})

# Ask about specific needs for canceling train tickets (example)
get_cancel_train_ticket_requirement_node = chattree.create_node( "#single_turn_interact#", {
    "infoitem": "{specific_requirements_for_canceling_train_tickets}",
    "infoitem_modifier": ["required"],
    "system_question": "What are your specific needs for canceling train tickets?",
})

# Prompt that the request to cancel the train ticket has been received (example)
inform_user_after_cancel_train_ticket_requirement_node = chattree.create_node( "#inform_user#", {
    "inform_content": "Your request to change your train ticket has been received",
})

# Intent branch: Book a hotel
book_hotel_intent_node = chattree.create_node( "#user_intent#", {
    "intent":"Book a hotel",
    "re_enter_intent":"Rebook another hotel"
})

# Ask about specific needs for hotel reservations (example)
get_book_hotel_requirement_node = chattree.create_node( "#single_turn_interact#", {
    "infoitem": "{specific_needs_for_hotel_reservations}",
    "infoitem_modifier": ["required"],
    "system_question": "What are your specific requirements for booking a hotel?",
})

# Prompt that the request for hotel reservation has been received (example)
inform_user_after_book_hotel_requirement_node = chattree.create_node( "#inform_user#", {
    "inform_content": "Your hotel reservation request has been received",
})

# Intent branch: Modify hotel reservation
change_hotel_intent_node = chattree.create_node( "#user_intent#", {
    "intent":"Modify hotel reservation",
    "re_enter_intent":"Remodify another hotel reservation"
})

# Inquire about specific needs for modifying hotel reservations (example)
get_change_hotel_requirement_node = chattree.create_node( "#single_turn_interact#", {
    "infoitem": "{modify_specific_requests_for_hotel_reservations}",
    "infoitem_modifier": ["required"],
    "system_question": "What are your specific needs for modifying your hotel reservation?",
})

# Prompt that a request to modify the hotel reservation has been received (example)
inform_user_after_change_hotel_requirement_node = chattree.create_node( "#inform_user#", {
    "inform_content": "Your request to modify your hotel reservation has been received",
})

# Intent branch: Cancel hotel reservation
cancel_hotel_intent_node = chattree.create_node( "#user_intent#", {
    "intent":"Cancel hotel reservation",
    "re_enter_intent":"Re-cancel another hotel reservation"
})

# Ask about specific needs for hotel cancellation (example)
get_cancel_hotel_requirement_node = chattree.create_node( "#single_turn_interact#", {
    "infoitem": "{specific_requirements_for_canceling_hotel_reservations}",
    "infoitem_modifier": ["required"],
    "system_question": "What are your specific needs for canceling a hotel reservation?",
})

# Prompt that the request to cancel the hotel reservation has been received (example)
inform_user_after_cancel_hotel_requirement_node = chattree.create_node( "#inform_user#", {
    "inform_content": "Your request to cancel your hotel reservation has been received",
})

# -------------------------------------------------------------------------------------
# Complete topology, ">>" represents the connection relationship between nodes, and the connection relationship here also determines the flow of the dialogue.
# -------------------------------------------------------------------------------------

start_node >> first_question_node >> [
    book_flight_ticket_intent_node   >> call_book_flight_ticket_sub_tree_node,
    change_flight_ticket_intent_node >> get_change_flight_ticket_requirement_node >> inform_user_after_get_change_flight_ticket_requirement_node,
    cancel_flight_ticket_intent_node >> get_cancel_flight_ticket_requirement_node >> inform_user_after_get_cancel_flight_ticket_requirement_node,
    book_train_ticket_intent_node    >> get_book_train_ticket_requirement_node >> inform_user_after_get_book_train_ticket_requirement_node,
    change_train_ticket_intent_node  >> get_change_train_ticket_requirement_node >> inform_user_after_change_train_ticket_requirement_node,
    cancel_train_ticket_intent_node  >> get_cancel_train_ticket_requirement_node >> inform_user_after_cancel_train_ticket_requirement_node,
    book_hotel_intent_node   >> get_book_hotel_requirement_node >> inform_user_after_book_hotel_requirement_node,
    change_hotel_intent_node >> get_change_hotel_requirement_node >> inform_user_after_change_hotel_requirement_node,
    cancel_hotel_intent_node >> get_cancel_hotel_requirement_node >> inform_user_after_cancel_hotel_requirement_node,
]

# -------------------------------------------------------------------------------------
# The standard end of every python ChatTree file, the code that renders the ChatTree into an HTML file
# -------------------------------------------------------------------------------------

if __name__ == "__main__":
    chattree.render(__file__)