from sklearn.model_selection import RandomizedSearchCV, KFold
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score, make_scorer
from pathlib import Path



def write_hpValues(model_Name, HP_Values,dataset):
    Path("results/%s" % dataset).mkdir(parents=True, exist_ok=True)
    Path("results/%s/%s" % (dataset,model_Name)).mkdir(parents=True, exist_ok=True)
    file_name = r'results/%s/%s/BestParam.txt' % (dataset,model_Name)
    with open(file_name, 'a+') as x_file:
        x_file.write(str(HP_Values))
        x_file.write("\n----------------------------------------------------------")
    return 0


# parameters grid to select the best combination using the listed values
def XGB_hyperparameterTuning(X_train, Y_train, dataset):
    grid_Param={'booster': ['gbtree','gblinear','dart'],
                'nthread':[4,6,10,50,70,90,120],
                'eta': [1, 0.5, 0.25, 0.1, 0.05, 0.01,0.5, 0.025, 0.0001, 0.005, 0.001, 0.0005, 0.00001],
                'max_depth': range(3, 20, 2),
                'min_child_weight': range(1, 12, 2),
                'gamma': [i / 10.0 for i in range(0, 5)],
                'subsample': [i / 10.0 for i in range(6, 10)],
                'colsample_bytree': [i / 10.0 for i in range(6, 10)],
                'reg_alpha': [1e-5, 1e-2, 0.1, 1, 100]
                }
    kfold = KFold(n_splits=5, shuffle=True, random_state=42)
    XGB = XGBClassifier()
    grid_search = RandomizedSearchCV(estimator= XGB, param_distributions=grid_Param, n_iter=100, cv=kfold, verbose=2 , scoring='accuracy',error_score=0, random_state=42, n_jobs=-1)
    grid_search.fit(X_train, Y_train)
    best_grid = grid_search.best_estimator_
    write_hpValues('XGB', str(best_grid), dataset)

    print(grid_search.best_estimator_)
    return grid_search


def XGB_training_tuning(X_train,Y_train, dataset):

    best_random = XGB_hyperparameterTuning(X_train,Y_train, dataset)
    Trained_model = XGBClassifier(**best_random.best_params_)
    Trained_model.fit(X_train,Y_train)
    return Trained_model
