import dataiku
import random
import re
import numpy as np

customers_df = (
    dataiku.Dataset("customers")
    .get_dataframe()
    .replace(np.nan, 'None', regex=True)
    .set_index("id")
)

def get_customer_id(name: str):
    """
    Provide the customer id, given the customer's name.
    This is the first thing to do if the customer's id is unknown.
    The input should be a a string like 'Smith' or 'Jane Snow' (without titles like "Mr.", "Mrs."...)
    """
    if len(name) == 0:
        return "No customer with this name. A name should be provided, e.g. 'Smith' or 'Jane Snow'"
    
    words = (''.join(x if x.isalnum() else ' ' for x in name)).lower().split()
    mask = customers_df.apply(lambda row: all(
        w in row['first_name'].lower() 
        or w in row['last_name'].lower()
        for w in words
    ), axis=1)

    if sum(mask) == 0:
        return "No customer with this name. A name should be provided, e.g. 'Smith' or 'Jane Snow'"

    result = """\n| customer | id |
    |---|---|"""
    
    masked = customers_df[mask]
    for row in masked.iterrows():
        result += f"\n| {row[1].first_name} {row[1].last_name} | {row[0]} |"
    if len(masked) > 1:
        result += "\nThere is more than 1 result. Please be more specific"
    return result

def get_details(customer_id: int):
    """
    Provide the details of the customer (identity, address, email address, subscription date, options).
    Useful when you need to know the options of the customer.
    """
    try:
        row = customers_df.loc[customer_id]
        name = f"{row.title} {row.first_name} {row.last_name}"
        return f"{name} (customer id: {customer_id}), address: {row.address}, email: {row.email_address}, subscription date: {row.subscription_date}, options: {row.options}"
    except KeyError:
        return "Unknown customer id"

def reset_password(customer_id: int):
    """
    Reset the password of the customer.
    """
    try:
        row = customers_df.loc[customer_id]
        return f"Email sent so that customer #{customer_id} can define a new password. No further action is needed to reinitialize the password."
    except KeyError:
        return "Unknown customer id"

def schedule_local_intervention(customer_id: int):
    """
    Send an email allowing the customer to schedule an appointment for a technician's visit.
    """
    try:
        row = customers_df.loc[customer_id]
        return f"Email sent to customer #{customer_id} to plan the visit of a technician. No further action is needed to handle an Internet connection problem."
    except KeyError:
        return "Unknown customer id"

def schedule_distant_intervention(customer_id: int):
    """
    Send an email allowing the customer to schedule an appointment for a a phone discussion with a technician.
    """
    try:
        row = customers_df.loc[customer_id]
        return f"Email sent to customer #{customer_id} to plan a phone discussion with a technician. No further action is needed to handle an Internet connection problem."
    except KeyError:
        return "Unknown customer id"

def cancel_appointment(customer_id: int):
    """
    Cancel an upcoming appointment. An appointment needs to be canceled before planning a new appointment.
    """
    try:
        row = customers_df.loc[customer_id]
        return f"Upcoming appointment canceled for customer #{customer_id}"
    except KeyError:
        return "Unknown customer id"

def run_diagnostics(customer_id: int):
    """
    Determine the best course of action when the customer experiences an Internet connection problem.
    """
    try:
        row = customers_df.loc[customer_id]
        situation = customer_id%3
        if situation == 0:
            return f"The customer can directly solve the connection problem by following the instructions provided in the FAQ: www.telco-operator/faq/{customer_id + 2}. An intervention of a technician is not warranted."
        elif situation == 1:
            return f"A technician must visit the customer to solve the connection problem. An appointment needs to be made"
        else:
            return f"A technician must discuss with the customer over the phone to solve the connection problem. An appointment needs to be made"
    except KeyError:
        return "Unknown customer id"

def sign_up_to_option(customer_id: int, option: str):
    """
    Activate an option for the customer's Internet plan.
    Only use this action if the customer explicitly requested a new option.
    Use this action once for each option.
    The two available options are 'TV' and 'Premium'.
    """
    option = option.lower()
    if option in ["tv", "premium"]:
        option_label = "TV" if option == "tv" else "Premium"
        try:
            if option_label not in customers_df.loc[customer_id, "options"]:
                return f"The {option_label} option has successfully been activated for customer #{customer_id}"
            else:
                return f"The {option_label} option was already activated for customer #{customer_id}"
        except KeyError:
            return "Unknown customer id"
    else:
        return "Incorrect input. The input for the option should be either 'TV' or 'Premium'"

def cancel_option(customer_id: int, option: str):
    """
    Dectivate an option for the customer's Internet plan.
    Only use this action if the customer explicitly asked one option to be cancelled.
    Use this action once for each option.
    The two available options are 'TV' and 'Premium'.
    """
    option = option.lower()
    if option in ["tv", "premium"]:
        option_label = "TV" if option == "tv" else "Premium"
        try:
            if option_label in customers_df.loc[customer_id, "options"]:
                return f"The {option_label} option has successfully been deactivated for customer #{customer_id}"
            else:
                return f"The {option_label} option was not activated for customer #{customer_id}"
        except KeyError:
            return "Unknown customer id"
    else:
        return "Incorrect input. The input for the option should be either 'TV' or 'Premium'"