from prediction.endpoints import algorithm_client_pulse as endpoints
from prediction import request_utils


def get_timeline(auth, user, limit, info=False):
    """
    Get the timeline of activities for a user on the ecosystem-server

    :param auth: Authentication token generated by the jwt_access module
    :param user: The user to get the timeline for
    :param limit: The number of activities to return
    """
    ep = endpoints.GET_TIMELINE
    param_dict = {
        "user": user,
        "limit": limit
    }
    resp = request_utils.create(auth, ep, params=param_dict, info=info)
    meta = resp.json()
    return meta


def process_basket(auth, dbcust, colcust, searchcust, custfield, dbitem, colitem, itemfield, supportcount, info=False):
    """
    Perform apriori basket analysis for specified data sets of customers and items

    :param auth: Authentication token generated by the jwt_access module
    :param dbcust: The database containing the customer data
    :param colcust: The collection containing the customer data
    :param searchcust: The search criteria for the customer data in the form of a mongoDB query
    :param custfield: The field in the customer data to use for the analysis
    :param dbitem: The database containing the item data
    :param colitem: The collection containing the item data
    :param itemfield: The field in the item data to use for the analysis
    :param supportcount: The minimum number of times an item must appear in the data to be included in the analysis
    """
    #TODO: Improve documentation
    ep = endpoints.PROCESS_BASKET
    param_dict = {
        "dbCust": dbcust,
        "colCust": colcust,
        "searchCust": searchcust,
        "custField": custfield,
        "dbItem": dbitem,
        "colItem": colitem,
        "itemField": itemfield,
        "supportCount": supportcount
    }
    resp = request_utils.create(auth, ep, params=param_dict, info=info)
    meta = resp.json()
    return meta


def process_directed_graph(auth, graphMeta, graphParam, info=False):
    """
    Analyze graph from data using graph meta data and analysis parameters.

    :param auth: Authentication token generated by the jwt_access module
    :param graphMeta: Example - {"vertex":[0,1],"edges":[{"from":0,"to":1}],"from":0,"source":"/data/data.csv","dotfile":"/data/data.dot","to":1}
    :param graphParam: Example - {"destination":"Bakeries","source":"12345678"}
    """
    #TODO: Improve documentation
    ep = endpoints.PROCESS_BASKET
    param_dict = {
        "graphMeta": graphMeta,
        "graphParam": graphParam
    }
    resp = request_utils.create(auth, ep, params=param_dict, info=info)
    meta = resp.json()
    return meta


def generate_forecast(auth, attribute, collection, collectionOut, database, dateattribute, find, historicsteps, steps,
                      info=False):
    ep = endpoints.GENERATE_FORECAST
    param_dict = {
        "attribute": attribute,
        "collection": collection,
        "collectionOut": collectionOut,
        "database": database,
        "dateattribute": dateattribute,
        "find": find,
        "historicsteps": historicsteps,
        "steps": steps
    }
    resp = request_utils.create(auth, ep, params=param_dict, info=info)
    meta = resp.json()
    return meta


def process_apriori(auth, colItem, collection, collectionOut, custField, database, dbItem, find, itemField,
                    supportCount, info=False):
    ep = endpoints.PROCESS_APRIORI
    param_dict = {
        "colItem": colItem,
        "collection": collection,
        "collectionOut": collectionOut,
        "custField": custField,
        "database": database,
        "dbItem": dbItem,
        "find": find,
        "itemField": itemField,
        "supportCount": supportCount
    }
    resp = request_utils.create(auth, ep, params=param_dict, info=info)
    meta = resp.json()
    return meta


def process_ecogenetic_network(auth, collection, collectionOut, database, find, graphMeta, graphParam, info=False):
    ep = endpoints.PROCESS_ECOGENETIC_NETWORK
    param_dict = {
        "collection": collection,
        "collectionOut": collectionOut,
        "database": database,
        "find": find,
        "graphMeta": graphMeta,
        "graphParam": graphParam
    }
    resp = request_utils.create(auth, ep, params=param_dict, info=info)
    meta = resp.json()
    return meta


def process_directed_graph2(auth, db, collection, collection_out, graphMeta, graphParam, info=False):
    # Analyze graph from data using graph meta data and analysis parameters.
    # Meta data format example: {"vertex":[0,1],"edges":[{"from":0,"to":1}],"from":0,"source":"/data/data.csv","dotfile":"/data/data.dot","to":1} Analysis parameter example: {"destination":"Bakeries","source":"12345678"}
    # Columns in file start at 0 and is sequenced.
    #   auth: Authentication token generated by jwt_access.Authenticate()
    #   graphMeta: (str)
    #   graphParam: (str)
    ep = endpoints.PROCESS_DIRECTED_GRAPH2
    param_dict = {
        "database": db,
        "collection": collection,
        "collectionOut": collection_out,
        "graphMeta": graphMeta,
        "graphParam": graphParam
    }
    resp = request_utils.create(auth, ep, params=param_dict, info=info)
    meta = resp.json()
    return meta


def generate_cox_ph_data(auth, collection, collection_out, customer_field, database, database_out, date_field, find,
                         info=False):
    ep = endpoints.GENERATE_COX_PH_DATA
    param_dict = {
        "collection": collection,
        "collectionOut": collection_out,
        "customer_field": customer_field,
        "database": database,
        "databaseOut": database_out,
        "date_field": date_field,
        "find": find
    }
    resp = request_utils.create(auth, ep, params=param_dict, info=info)
    meta = resp.json()
    return meta


def process_arima_forecast(auth, json, info=False):
    ep = endpoints.PROCESS_ARIMA_FORECAST
    resp = request_utils.create(auth, ep, json=json, info=info)
    response = resp.json()
    return response


def list_pulse_responder_dynamic(auth, info=False):
    """
    List all dynamic interaction configurations on the ecosystem-server

    :param auth: Authentication token generated by the jwt_access module
    """
    ep = endpoints.LIST_PULSE_RESPONDER_DYNAMIC
    resp = request_utils.create(auth, ep, info=info)
    result = resp.json()
    return result


def delete_pulse_responder_dynamic(auth, db, collection, find, info=False):
    """
    Delete a dynamic interaction configuration on the ecosystem-server

    :param auth: Authentication token generated by the jwt_access module
    :param db: The database containing the configuration
    :param collection: The collection containing the configuration
    :param find: The search criteria for the configuration in the form of a mongoDB query. The find query should be of the form {"uuid": "e95bfe26-db16-4e64-9ea5-b7cf3c43f4cb"} where the uuid is the unique identifier of the configuration
    """
    ep = endpoints.DELETE_PULSE_RESPONDER_DYNAMIC
    param_dict = {
        "database": db,
        "collection": collection,
        "find": find,
    }
    resp = request_utils.create(auth, ep, params=param_dict, info=info)
    result = resp.json()
    return result


def get_pulse_responder_messages(auth, db, collection, info=False):
    """
    Deprecated
    """
    ep = endpoints.GET_PULSE_RESPONDER_MESSAGES
    param_dict = {
        "database": db,
        "collection": collection,
    }
    resp = request_utils.create(auth, ep, params=param_dict, info=info)
    result = resp.json()
    return result


def get_pulse_responder_options(auth, params, info=False):
    """
    Get the options store for a dynamic interaction configuration on the ecosystem-server

    :param auth: Authentication token generated by the jwt_access module
    :param params: A dictionary of parameters specify the options store to retrieve, Must be a dictionary of the form {"database": "", "collection": "", "find": {}, "skip": 0, "limit": 0}
    """
    ep = endpoints.GET_PULSE_RESPONDER_OPTIONS
    param_dict = {
        "params": params,
    }
    resp = request_utils.create(auth, ep, params=param_dict, info=info)
    result = resp.json()
    return result


def get_pulse_responder_profile(auth, db, collection, info=False):
    """
    Deprecated
    """
    ep = endpoints.GET_PULSE_RESPONDER_PROFILE
    param_dict = {
        "database": db,
        "collection": collection,
    }
    resp = request_utils.create(auth, ep, params=param_dict, info=info)
    result = resp.json()
    return result


def update_client_pulse_responder(auth, json, info=False):
    #TODO: Improve documentation
    ep = endpoints.UPDATE_CLIENT_PULSE_RESPONDER
    resp = request_utils.create(auth, ep, json=json, info=info)
    response = resp.json()
    return response


def save_pulse_responder_dynamic(auth, json, info=False):
    """
    Save Dynamic interaction configuration to the ecosystem-server

    :param auth: Authentication token generated by the jwt_access module
    :param json: The configuration to save in json format. See an example of the required format in the example below

    Examples:

    .. code-block:: python
    
        acp.save_pulse_responder_dynamic(auth, {
            {
            "name": "telco_segmented_offers",
            "description": "Ecosystem Rewards recommender to select offers for telco customers",
            "date_updated": "2023-12-12T07:43:57.000586Z",
            "batch": "false",
            "score_database": "ecosystem_meta",
            "score_connection": "http://ecosystem-runtime:8091",
            "score_collection": "dynamic_engagement",
            "properties": "predictor.corpora=[{uuid:'e9063bc0-d7ec-4af8-877d-fb4288fe7eac', type:'dynamic_engagement', name:'dynamic_engagement', database:'mongodb', db:'ecosystem_meta', table:'dynamic_engagement', update:true} ,{uuid:'e9063bc0-d7ec-4af8-877d-fb4288fe7eac', type:'dynamic_engagement_options', name:'dynamic_engagement',database:'mongodb', db:'prod_telco_super_rec', table:'telco_segmented_deals_set_up_feature_store_options', update:true}]",
            "feature_store_database": "prod_telco_super_rec",
            "feature_store_collection": "telco_segmented_deals_set_up_feature_store",
            "feature_store_connection": "",
            "options_store_database": "prod_telco_super_rec",
            "options_store_collection": "telco_segmented_deals_set_up_feature_store_options",
            "options_store_connection": "",
            "uuid": "e9063bc0-d7ec-4af8-877d-fb4288fe7eac",
            "randomisation": {
                "approach": "binaryThompson",
                "test_options_across_segment": "",
                "epsilon": 0,
                "success_reward": 0.1,
                "fail_reward": 0.01,
                "prior_success_reward": 0.1,
                "prior_fail_reward": 1,
                "cross_segment_epsilon": 0.05,
                "cache_duration": 600000,
                "processing_window": "0",
                "processing_count": "0",
                "decay_gamma": 1,
                "interaction_count": "0",
                "calendar": "None",
                "batch": "false",
                "learning_rate": 0.25,
                "discount_factor": 0.75,
                "random_action": 0.2,
                "max_reward": 10
            },
            "contextual_variables": {
                "contextual_variable_one_name": "segments",
                "contextual_variable_two_name": "",
                "contextual_variable_one_values": [
                "Default",
                "Apparel",
                "LowSpender"
                ],
                "contextual_variable_two_values": "",
                "contextual_variable_one_from_data_source": true,
                "contextual_variable_two_from_data_source": false,
                "contextual_variable_one_lookup": "ts_segment",
                "contextual_variable_two_lookup": "",
                "offer_key": "offer",
                "offer_values": "",
                "take_up": "",
                "tracking_key": ""
            },
            "virtual_variables": [],
            "lookup_fields": [
                "subs_id",
                "ts_segment",
                "user_id",
                "telco_dt"
            ],
            "batch_settings": {
                "batch_outline": "",
                "pulse_responder_list": "",
                "execution_type": "",
                "database": "",
                "collection": "",
                "threads": 7,
                "find": "{}",
                "database_out": "",
                "collection_out": "",
                "campaign": "",
                "number_of_offers": 3,
                "userid": "",
                "options": "",
                "contextual_variables": "",
                "batchUpdateMessage": ""
            },
            "options": {
                "search": "{}",
                "skip": 0,
                "limit": 100,
                "options": []
            }
            }
        })

    """
    ep = endpoints.SAVE_PULSE_RESPONDER_DYNAMIC
    resp = request_utils.create(auth, ep, json=json, info=info)
    response = resp.json()
    return response
