import numpy as np
from .experiments import run_experiments
from ..plots import colors
from .. import __version__
from . import models
from . import methods
from . import metrics
import sklearn
import io
import base64
import os
try:
    import matplotlib.pyplot as pl
    import matplotlib
except ImportError:
    pass


metadata = {
    # "runtime": {
    #     "title": "Runtime",
    #     "sort_order": 1
    # },
    # "local_accuracy": {
    #     "title": "Local Accuracy",
    #     "sort_order": 2
    # },
    # "consistency_guarantees": {
    #     "title": "Consistency Guarantees",
    #     "sort_order": 3
    # },
    # "keep_positive_mask": {
    #     "title": "Keep Positive (mask)",
    #     "xlabel": "Max fraction of features kept",
    #     "ylabel": "Mean model output",
    #     "sort_order": 4
    # },
    # "keep_negative_mask": {
    #     "title": "Keep Negative (mask)",
    #     "xlabel": "Max fraction of features kept",
    #     "ylabel": "Negative mean model output",
    #     "sort_order": 5
    # },
    # "keep_absolute_mask__r2": {
    #     "title": "Keep Absolute (mask)",
    #     "xlabel": "Max fraction of features kept",
    #     "ylabel": "R^2",
    #     "sort_order": 6
    # },
    # "keep_absolute_mask__roc_auc": {
    #     "title": "Keep Absolute (mask)",
    #     "xlabel": "Max fraction of features kept",
    #     "ylabel": "ROC AUC",
    #     "sort_order": 6
    # },
    # "remove_positive_mask": {
    #     "title": "Remove Positive (mask)",
    #     "xlabel": "Max fraction of features removed",
    #     "ylabel": "Negative mean model output",
    #     "sort_order": 7
    # },
    # "remove_negative_mask": {
    #     "title": "Remove Negative (mask)",
    #     "xlabel": "Max fraction of features removed",
    #     "ylabel": "Mean model output",
    #     "sort_order": 8
    # },
    # "remove_absolute_mask__r2": {
    #     "title": "Remove Absolute (mask)",
    #     "xlabel": "Max fraction of features removed",
    #     "ylabel": "1 - R^2",
    #     "sort_order": 9
    # },
    # "remove_absolute_mask__roc_auc": {
    #     "title": "Remove Absolute (mask)",
    #     "xlabel": "Max fraction of features removed",
    #     "ylabel": "1 - ROC AUC",
    #     "sort_order": 9
    # },
    # "keep_positive_resample": {
    #     "title": "Keep Positive (resample)",
    #     "xlabel": "Max fraction of features kept",
    #     "ylabel": "Mean model output",
    #     "sort_order": 10
    # },
    # "keep_negative_resample": {
    #     "title": "Keep Negative (resample)",
    #     "xlabel": "Max fraction of features kept",
    #     "ylabel": "Negative mean model output",
    #     "sort_order": 11
    # },
    # "keep_absolute_resample__r2": {
    #     "title": "Keep Absolute (resample)",
    #     "xlabel": "Max fraction of features kept",
    #     "ylabel": "R^2",
    #     "sort_order": 12
    # },
    # "keep_absolute_resample__roc_auc": {
    #     "title": "Keep Absolute (resample)",
    #     "xlabel": "Max fraction of features kept",
    #     "ylabel": "ROC AUC",
    #     "sort_order": 12
    # },
    # "remove_positive_resample": {
    #     "title": "Remove Positive (resample)",
    #     "xlabel": "Max fraction of features removed",
    #     "ylabel": "Negative mean model output",
    #     "sort_order": 13
    # },
    # "remove_negative_resample": {
    #     "title": "Remove Negative (resample)",
    #     "xlabel": "Max fraction of features removed",
    #     "ylabel": "Mean model output",
    #     "sort_order": 14
    # },
    # "remove_absolute_resample__r2": {
    #     "title": "Remove Absolute (resample)",
    #     "xlabel": "Max fraction of features removed",
    #     "ylabel": "1 - R^2",
    #     "sort_order": 15
    # },
    # "remove_absolute_resample__roc_auc": {
    #     "title": "Remove Absolute (resample)",
    #     "xlabel": "Max fraction of features removed",
    #     "ylabel": "1 - ROC AUC",
    #     "sort_order": 15
    # },
    # "remove_positive_retrain": {
    #     "title": "Remove Positive (retrain)",
    #     "xlabel": "Max fraction of features removed",
    #     "ylabel": "Negative mean model output",
    #     "sort_order": 11
    # },
    # "remove_negative_retrain": {
    #     "title": "Remove Negative (retrain)",
    #     "xlabel": "Max fraction of features removed",
    #     "ylabel": "Mean model output",
    #     "sort_order": 12
    # },
    # "keep_positive_retrain": {
    #     "title": "Keep Positive (retrain)",
    #     "xlabel": "Max fraction of features kept",
    #     "ylabel": "Mean model output",
    #     "sort_order": 6
    # },
    # "keep_negative_retrain": {
    #     "title": "Keep Negative (retrain)",
    #     "xlabel": "Max fraction of features kept",
    #     "ylabel": "Negative mean model output",
    #     "sort_order": 7
    # },
    # "batch_remove_absolute__r2": {
    #     "title": "Batch Remove Absolute",
    #     "xlabel": "Fraction of features removed",
    #     "ylabel": "1 - R^2",
    #     "sort_order": 13
    # },
    # "batch_keep_absolute__r2": {
    #     "title": "Batch Keep Absolute",
    #     "xlabel": "Fraction of features kept",
    #     "ylabel": "R^2",
    #     "sort_order": 8
    # },
    # "batch_remove_absolute__roc_auc": {
    #     "title": "Batch Remove Absolute",
    #     "xlabel": "Fraction of features removed",
    #     "ylabel": "1 - ROC AUC",
    #     "sort_order": 13
    # },
    # "batch_keep_absolute__roc_auc": {
    #     "title": "Batch Keep Absolute",
    #     "xlabel": "Fraction of features kept",
    #     "ylabel": "ROC AUC",
    #     "sort_order": 8
    # },
    
    # "linear_shap_corr": {
    #     "title": "Linear SHAP (corr)"
    # },
    # "linear_shap_ind": {
    #     "title": "Linear SHAP (ind)"
    # },
    # "coef": {
    #     "title": "Coefficents"
    # },
    # "random": {
    #     "title": "Random"
    # },
    # "kernel_shap_1000_meanref": {
    #     "title": "Kernel SHAP 1000 mean ref."
    # },
    # "sampling_shap_1000": {
    #     "title": "Sampling SHAP 1000"
    # },
    # "tree_shap_tree_path_dependent": {
    #     "title": "Tree SHAP"
    # },
    # "saabas": {
    #     "title": "Saabas"
    # },
    # "tree_gain": {
    #     "title": "Gain/Gini Importance"
    # },
    # "mean_abs_tree_shap": {
    #     "title": "mean(|Tree SHAP|)"
    # },
    # "lasso_regression": {
    #     "title": "Lasso Regression"
    # },
    # "ridge_regression": {
    #     "title": "Ridge Regression"
    # },
    # "gbm_regression": {
    #     "title": "Gradient Boosting Regression"
    # }
}

benchmark_color_map = {
    "tree_shap": "#1E88E5",
    "deep_shap": "#1E88E5",
    "linear_shap_corr": "#1E88E5",
    "linear_shap_ind": "#ff0d57",
    "coef": "#13B755",
    "random": "#999999",
    "const_random": "#666666",
    "kernel_shap_1000_meanref": "#7C52FF"
}

# negated_metrics = [
#     "runtime",
#     "remove_positive_retrain",
#     "remove_positive_mask",
#     "remove_positive_resample",
#     "keep_negative_retrain",
#     "keep_negative_mask",
#     "keep_negative_resample"
# ]

# one_minus_metrics = [
#     "remove_absolute_mask__r2",
#     "remove_absolute_mask__roc_auc",
#     "remove_absolute_resample__r2",
#     "remove_absolute_resample__roc_auc"
# ]

def get_method_color(method):
    for l in getattr(methods, method).__doc__.split("\n"):
        l = l.strip()
        if l.startswith("color = "):
            v = l.split("=")[1].strip()
            if v.startswith("red_blue_circle("):
                return colors.red_blue_circle(float(v[16:-1]))
            else:
                return v
    return "#000000"

def get_method_linestyle(method):
    for l in getattr(methods, method).__doc__.split("\n"):
        l = l.strip()
        if l.startswith("linestyle = "):
            return l.split("=")[1].strip()
    return "solid"

def get_metric_attr(metric, attr):
    for l in getattr(metrics, metric).__doc__.split("\n"):