# coding: utf-8
"""new clicks for search-query"""

from .calc import get_reference, make_cached_nearest_vals_from_reference

# dict<phrase_words_cnt, dict<imp_cnt, coeff> >
CTR_IMPROVEMENT = {
    1: {1: 1.17, 2: 1.19, 3: 1.22, 4: 1.26, 5: 1.30, 6: 1.51},
    2: {1: 1.21, 2: 1.27, 3: 1.34, 4: 1.43, 5: 1.62},
    3: {1: 1.19, 2: 1.24, 3: 1.30, 4: 1.43},
    4: {1: 1.17, 2: 1.21, 3: 1.30},
    5: {1: 1.19, 2: 1.24},
    6: {1: 1.19}}

# dict<tuple(phrase_words_cnt, improvement_len), improvement_ctr>
CTR_IMPROVEMENT = {(p, i): CTR_IMPROVEMENT[p][i] for p in CTR_IMPROVEMENT for i in CTR_IMPROVEMENT[p]}

nearest_vals_from_reference = make_cached_nearest_vals_from_reference()


def calc_weighted_ctr(reference, row):

    CONFEDENCE_L = 100.0  # Shows

    ref = nearest_vals_from_reference(
        reference,
        row["PhraseWordsCnt"],
        row["QueryWordsCnt"])
    ref_ctr = ref["Clicks"] / ref["Shows"]

    fact_ctr = row["Clicks"] / float(row["Shows"])

    confedence = min(row["Shows"], CONFEDENCE_L) / float(CONFEDENCE_L)

    return fact_ctr * confedence + ref_ctr * (1 - confedence)


def new_ctr(improvements, reference, row):

    imp_cnt = max(0, min(row["QueryWordsCnt"], 7) - min(row["PhraseWordsCnt"], 7))

    if imp_cnt == 0:
        new_ctr = row["Clicks"] / float(row["Shows"])
    else:
        change_coef = improvements[(min(row["PhraseWordsCnt"], 6), imp_cnt)]
        new_ctr = calc_weighted_ctr(reference, row) * change_coef

    return new_ctr


def new_ctr_col(df):

    # DataFrame :: index = ("PhraseWordsCnt", "QueryWordsCnt"); cols = Shows, Clicks, Cost
    REFERENCE = get_reference(df, shows=100, clicks=10)
    new_clicks_for_row = lambda row: new_ctr(CTR_IMPROVEMENT, REFERENCE, row)

    return df.apply(new_clicks_for_row, axis=1)
