const TEXT_EXPORTS = `# Generated by AutoProfiler`
const VIS_EXPORTS = `# Generated by AutoProfiler

import altair as alt`
const disableMaxRowsCode = 'alt.data_transformers.disable_max_rows()'


// ~~~~~~~~~ EXPORT Text Fact CODE ~~~~~~~~~

export const SD_OUTLIERS = (
    df_name: string,
    col_name: string,
    isIndex: boolean,
) => {
    let col_stmt: string;
    if (isIndex) {
        col_stmt = ".index.to_series()";
    } else {
        col_stmt = `["${col_name}"]`;
    };
    return `${TEXT_EXPORTS}
sd = ${df_name}${col_stmt}.std()
mean = ${df_name}${col_stmt}.mean()
_normalized_sd = (${df_name}${col_stmt} - mean) / sd

# dataframe with only outliers
outliers_sd = ${df_name}[abs(_normalized_sd) > 3]

# dataframe without outliers
no_outliers_sd = ${df_name}[abs(_normalized_sd) <= 3]`
}

export const IQR_OUTLIERS = (
    df_name: string,
    col_name: string,
    isIndex: boolean,
) => {
    let col_stmt: string;
    if (isIndex) {
        col_stmt = ".index.to_series()";
    } else {
        col_stmt = `["${col_name}"]`;
    };
    return `${TEXT_EXPORTS}
q1, q3 = ${df_name}${col_stmt}.quantile(0.25), ${df_name}${col_stmt}.quantile(0.75)
iqr = q3 - q1
lower = q1 - 1.5 * iqr
upper = q3 + 1.5 * iqr

# dataframe with only outliers
outliers_iqr = ${df_name}[(${df_name}${col_stmt} < lower) | (${df_name}${col_stmt} > upper)]

# dataframe without outliers
no_outliers_iqr= ${df_name}[(${df_name}${col_stmt} >= lower) & (${df_name}${col_stmt} <= upper)]`;
}


export const DUPLICATES = (
    df_name: string,
    col_name: string,
    isIndex: boolean,
) => {
    let col_stmt: string;
    if (isIndex) {
        col_stmt = ".index.to_series()";
    } else {
        col_stmt = `["${col_name}"]`;
    };
    return `${TEXT_EXPORTS}
# dataframe with duplicate values for ${col_name}
duplicates = ${df_name}[${df_name}${col_stmt}.duplicated()]`;
}


// ~~~~~~~~~ EXPORT Chart CODE ~~~~~~~~~


export const QUANT_CHART = (
    df_name: string,
    col_name: string,
    numbins = 8,
    isIndex = false
) => {
    let col_stmt: string;
    if (isIndex) {
        col_stmt = ".index.to_series()";
    } else {
        col_stmt = `["${col_name}"]`;
    };
    return `${VIS_EXPORTS} 
binned_series = ${df_name}${col_stmt}.value_counts(bins=${numbins}, sort=False)

chart_data_binned = pd.DataFrame({
    "leftbin": binned_series.index.left, 
    "rightbin": binned_series.index.right, 
    "count": binned_series.values
})

# move leftmost bin edge up since pandas does not put edge at the min
chart_data_binned.loc[0, "leftbin"] = ${df_name}${col_stmt}.min()

quant_chart = alt.Chart(chart_data_binned).mark_bar(color="#fca5a5").encode(
    x = alt.X("leftbin", bin="binned", title="${col_name} (binned)"),
    x2 = "rightbin",
    y = alt.Y("count")
).properties(
    width=500,
    height=200
)

quant_chart`;
}

export const CAT_CHART = (
    df_name: string,
    col_name: string,
    k = 10,
    isIndex = false
) => {
    let col_stmt: string;
    if (isIndex) {
        col_stmt = ".index.to_series()";
    } else {
        col_stmt = `["${col_name}"]`;
    };
    return `${VIS_EXPORTS}
topk_series = ${df_name}${col_stmt}.value_counts().iloc[:${k}]
topk_df = pd.DataFrame({"${col_name}":topk_series.index, 'count':topk_series.values})

cat_chart = alt.Chart(topk_df).mark_bar(color="#bae6fd").encode( 
    x = alt.X("count"),
    y = alt.Y("${col_name}", sort="-x")
).properties(
    width=500,
    height=200
)

cat_chart`;
}


export const TEMPORAL_CHART = (
    df_name: string,
    col_name: string,
    shouldDisableMaxRows = false,
    isIndex = false
) => {
    let col_stmt: string;
    if (isIndex) {
        col_stmt = ".index.to_series()";
    } else {
        col_stmt = `["${col_name}"]`;
    };
    return `${VIS_EXPORTS}
${shouldDisableMaxRows ? disableMaxRowsCode : ""}

temp_df = pd.DataFrame({"temp":${df_name}${col_stmt}})

temporal_chart = alt.Chart(temp_df).mark_line(color="#14b8a6").encode(
    x='temp:T',
    y='count()'
).properties(
    width=500,
    height=200
)

temporal_chart`;
}

// ~~~~~~~~~ EXPORT Selection CODE ~~~~~~~~~
export type CODE_EXPORT_TYPE = "min" | "25%" | "median" | "mean" | "75%" | "max";

export function exportCodeSelection(df_name: string, col_name: string, type: CODE_EXPORT_TYPE, isIndex = false) {

    let col_stmt: string;
    if (isIndex) {
        col_stmt = ".index.to_series()";
    } else {
        col_stmt = `["${col_name}"]`;
    };

    let agg_code = ""

    if (type === "min") {
        agg_code = `.min()`
    } else if (type === "25%") {
        agg_code = `.quantile(0.25)`
    } else if (type === "median") {
        agg_code = `.median()`
    } else if (type === "mean") {
        agg_code = `.mean()`
    } else if (type === "75%") {
        agg_code = `.quantile(0.75)`
    } else if (type === "max") {
        agg_code = `.max()`
    }

    if (agg_code) {
        return `${df_name}[ ${df_name}${col_stmt} == ${df_name}${col_stmt}${agg_code} ]`
    }

    return `${df_name}${col_stmt}`
}
