import argparse

from clv.newcomers import TrainLSTMNewComers
from clv.next_purchase_model import TrainLSTM
from clv.purchase_amount_model import TrainConv1Dimension


def main(
    job="train",
    order_count=None,
    customer_indicator=None,
    amount_indicator=None,
    data_source=None,
    data_query_path=None,
    time_period=None,
    time_indicator=None,
    export_path=None,
    date=None,
):
    """
    This is how we run the model prediction and train processes.
    Depending on the job it is triggered for train and prediction process individually.
    job, customer_indicator, amount_indicator, data_source, data_query_path, time_period, export_path are required.
    if **order_count** is null, it is detecting for optimum order count.
    the date is crucial for data query. (< date)

    :param job: train or prediction
    :param order_count: number of order for purchase amount model
    :param customer_indicator: customer column at data
    :param amount_indicator: amount column at data
    :param data_source: postgres, .csv, .json, awsredshift, bigquery.
    :param data_query_path: query or file_name (with whole path).
    :param time_period: a period of time which is willing to predict.
    :param time_indicator: time columns at data set
    :param export_path: where data, model,tuned_parameters, schedule arguments are stored
    :param date: given date of previous data (< date)
    :return: class TrainLSTM (Next Purchase Model) & class TrainConv1Dimension (Purchase Amount Model)
    """
    print(
        "received :",
        {
            "job": job,
            "order_count": order_count,
            "customer_indicator": customer_indicator,
            "amount_indicator": amount_indicator,
            "data_source": data_source,
            "data_query_path": data_query_path,
            "time_period": time_period,
            "time_indicator": time_indicator,
            "export_path": export_path,
        },
    )

    # engaged customers of CLV models train and prediction process
    next_purchase = TrainLSTM(
        date=date,
        time_indicator=time_indicator,
        order_count=order_count,
        data_source=data_source,
        data_query_path=data_query_path,
        time_period=time_period,
        directory=export_path,
        customer_indicator=customer_indicator,
        amount_indicator=amount_indicator,
    )
    if job == "train":
        next_purchase.train_execute()
    if job == "prediction":
        next_purchase.prediction_execute()
    if job == "train_prediction":
        next_purchase.train_execute()
        next_purchase.prediction_execute()

    predicted_orders = next_purchase.results
    raw_data = next_purchase.data
    del next_purchase

    purchase_amount = TrainConv1Dimension(
        date=date,
        time_indicator=time_indicator,
        order_count=order_count,
        data_source=data_source,
        data_query_path=data_query_path,
        time_period=time_period,
        directory=export_path,
        customer_indicator=customer_indicator,
        predicted_orders=predicted_orders,
        amount_indicator=amount_indicator,
    )

    if job == "train":
        purchase_amount.train_execute()
    if job == "prediction":
        purchase_amount.prediction_execute()
    if job == "train_prediction":
        purchase_amount.train_execute()
        purchase_amount.prediction_execute()

    engaged_customers_results = purchase_amount.results
    del purchase_amount

    # newcomers of CLV models train and prediction process
    newcomers = TrainLSTMNewComers(
        date=date,
        time_indicator=time_indicator,
        order_count=order_count,
        data_source=data_source,
        data_query_path=data_query_path,
        time_period=time_period,
        directory=export_path,
        customer_indicator=customer_indicator,
        engaged_customers_results=engaged_customers_results,
        amount_indicator=amount_indicator,
    )

    if job == "train":
        newcomers.train_execute()
    if job == "prediction":
        newcomers.prediction_execute()
    if job == "train_prediction":
        newcomers.train_execute()
        newcomers.prediction_execute()

    newcomers_clv = newcomers.results
    del newcomers

    return {
        "next_purchase": {"data": raw_data},
        "purchase_amount": {"results": engaged_customers_results},
        "newcomers": {"results": newcomers_clv},
    }


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-J",
        "--job",
        type=str,
        help="""
                                train, prediction
                        """,
    )
    parser.add_argument(
        "-OC",
        "--order_count",
        type=str,
        help="""
                                number of previous order count. It has been using for prediction next order frequency
                        """,
    )
    parser.add_argument(
        "-CI",
        "--customer_indicator",
        type=str,
        help="""identifier of the customer (id)

                        """,
    )
    parser.add_argument(
        "-AI",
        "--amount_indicator",
        type=str,
        help="""
                                data column n-amount (preferred numeric)
                        """,
    )
    parser.add_argument(
        "-DS",
        "--data_source",
        type=str,
        help="""
                        AWS RedShift, BigQuery, PostgreSQL, csv, json files can be connected to system
                        """,
        required=True,
    )
    parser.add_argument(
        "-DQP",
        "--data_query_path",
        type=str,
        help="""
                        if there is file for data importing;
                            must be the path (e.g /../.../ab_test_raw_data.csv)
                        if there is ac- connection such as PostgreSQL / BigQuery
                            query must at the format "SELECT++++*+++FROM++ab_test_table_+++"
                        """,
        required=True,
    )
    parser.add_argument(
        "-TI",
        "--time_indicator",
        type=str,
        help="""
                        This can only be applied with date. It can be week, week_part, quarter, year, month.
                        Individually time indicator checks the date part is significantly
                        a individual group for data set or not.
                        If it is uses time_indicator as a  group
                        """,
    )
    parser.add_argument(
        "-TP",
        "--time_period",
        type=str,
        help="""
                        This shows us to the time period
                        """,
    )
    parser.add_argument(
        "-EP",
        "--export_path",
        type=str,
        help="""
                        Exporting path of the results set. Csv file of exporting.
                        """,
    )
    arguments = parser.parse_args()
    args = {
        "job": arguments.job,
        "order_count": arguments.order_count,
        "customer_indicator": arguments.customer_indicator,
        "amount_indicator": arguments.amount_indicator,
        "data_source": arguments.data_source,
        "data_query_path": arguments.data_query_path,
        "time_period": arguments.time_period,
        "time_indicator": arguments.time_indicator,
        "export_path": arguments.export_path,
    }
    print(args)
    main(**args)
