# coding: utf-8
"""xlsx-queries:
  - 01_top_non-bolded_queries
  - 01_highlight_hist_queries
  - 02_nested_queries
  - 02_top_nested_queries
"""
from ..review import Recommendation, append_recommendation
from ..const import EXCEL_MAX_ROWS
import pandas as pd


def shows_by_words_cnt(df):
    "02_nested_queries"

    col1 = df.groupby(["PhraseWordsCnt"]).agg({"Shows": pd.np.sum})[["Shows"]]
    col1 = col1.loc[range(1, 8)]  # на случай когда не все длины есть
    col1.index.rename(u"Кол-во слов", inplace=True)
    col1.rename(columns={"Shows": u"Ключевые фразы"}, inplace=True)

    col2 = df.groupby(["QueryWordsCnt"]).agg({"Shows": pd.np.sum})[["Shows"]]
    col2.index.rename("WordsCnt", inplace=True)
    col2.rename(columns={"Shows": u"Запросы пользователей"}, inplace=True)

    df_chart = col1.join(col2).fillna(0)
    setattr(df_chart, "formats", {u"Ключевые фразы": "int", u"Запросы пользователей": "int"})
    return df_chart


def shows_by_nesting_type(df):
    "02_nested_queries"

    df_chart = df.loc[:, ["Shows", "PhraseWordsCnt", "QueryWordsCnt"]].copy()
    df_chart["isExactNesting"] = df_chart.apply(
        lambda fr: fr["QueryWordsCnt"] == fr["PhraseWordsCnt"],
        axis=1)
    df_chart = (df_chart
                .groupby(["QueryWordsCnt", "isExactNesting"])
                .agg({"Shows": sum})
                .unstack("isExactNesting")
                ["Shows"]
                .rename(columns={True: u"Точное соответствие", False: u"Широкое соответствие"})
                .loc[:, [u"Точное соответствие", u"Широкое соответствие"]]
                .fillna(0))
    df_chart.index.rename(u"Кол-во слов", inplace=True)
    df_chart.columns.rename("", inplace=True)

    total_shows = float(df_chart.values.sum())
    df_chart[u"Неоптимально"] = df_chart[u"Широкое соответствие"].apply(lambda x: x / total_shows)
    # range на случай не всех длин
    df_chart = df_chart.loc[range(1, 8), [u"Точное соответствие", u"Широкое соответствие", u"Неоптимально"]].fillna(0)

    setattr(df_chart, "formats", {u"Точное соответствие": "int",
                                  u"Широкое соответствие": "int",
                                  u"Неоптимально": "percent"})

    return df_chart


def new_clicks_by_words_cnt(df):
    "02_nested_queries"

    df_chart = (df.loc[
        df["QueryWordsCnt"] > df["PhraseWordsCnt"],
        ["NewClicksFromNested", "PhraseWordsCnt", "QueryWordsCnt"]]
        .groupby(["PhraseWordsCnt", "QueryWordsCnt"])
        .agg({"NewClicksFromNested": pd.np.sum})
        ["NewClicksFromNested"]
        .unstack("QueryWordsCnt"))

    df_chart.index.rename(u"Кол-во слов", inplace=True)

    # на случай когда не все длины есть
    # ограничено 6 словами, так как если у фразы 7 слов, то
    # прорабатывать нечего
    try:
        df_chart = df_chart.loc[range(1, 7), range(2, 8)].fillna(0)
        setattr(df_chart, "table_formats", "int")

        return df_chart
    except KeyError:
        return None


def total_clicks_from_nested(df):
    "02_nested_queries"

    df_chart = df.loc[:, [
        "QueryWordsCnt",
        "PhraseWordsCnt",
        "Clicks",
        "NewClicksFromNested"]].copy()
    df_chart["isExactNesting"] = df_chart.apply(
        lambda fr: fr["QueryWordsCnt"] == fr["PhraseWordsCnt"],
        axis=1)
    df_chart = df_chart.groupby("isExactNesting")[["Clicks", "NewClicksFromNested"]].sum().T
    df_chart.loc["NewClicksFromNested", True] = 0
    df_chart = df_chart.unstack().sum(level=1)
    df_chart["Gain"] = df_chart["NewClicksFromNested"] / df_chart["Clicks"]

    df_chart.rename(index={
        "NewClicksFromNested": u"Потенциал",
        "Clicks": u"Текущая ситуация",
        "Gain": u"Изменение"},
        inplace=True)

    df_chart = pd.DataFrame(df_chart, columns=[u"Клики"]).loc[[u"Текущая ситуация", u"Потенциал", u"Изменение"]]
    setattr(df_chart, "row_formats", {1: "int", 2: "int", 3: "gain"})

    new_clicks = df_chart.loc[u"Изменение", u"Клики"]
    # нижняя граница из головы эксперта, можно крутить
    if new_clicks > 0.05:
        Rec = Recommendation(
            dataframe=df,
            internal_sheet_name="02_nested_queries",
            title=u"Вложенные запросы",
            snippet=u"Есть возможность выделить вложенные запросы в самостоятельные ключевые фразы. Это может принести до %.0f%% дополнительных кликов за счёт увеличения CTR фраз" % (new_clicks * 100),
            importance_lvl=2,
            cell="K13")

        append_recommendation(df, Rec)

    return df_chart


def total_cost_from_nested(df):
    "02_nested_queries"

    df_chart = df.loc[:, [
        "QueryWordsCnt",
        "PhraseWordsCnt",
        "Cost",
        "NewCostFromNested"]].copy()
    df_chart["isExactNesting"] = df_chart.apply(
        lambda fr: fr["QueryWordsCnt"] == fr["PhraseWordsCnt"],
        axis=1)
    df_chart = df_chart.groupby("isExactNesting")[["Cost", "NewCostFromNested"]].sum().T
    df_chart.loc["NewCostFromNested", True] = 0
    df_chart = df_chart.unstack().sum(level=1)
    df_chart["Gain"] = df_chart["NewCostFromNested"] / df_chart["Cost"]

    df_chart.rename(index={
        "NewCostFromNested": u"Новые",
        "Cost": u"Фактические",
        "Gain": u"Изменение"},
        inplace=True)

    df_chart = pd.DataFrame(df_chart, columns=[u"Расходы"]).loc[[u"Фактические", u"Новые", u"Изменение"]]
    setattr(df_chart, "row_formats", {1: "float", 2: "float", 3: "gain"})

    return df_chart


def ctr_cpc_from_query_len(df):
    "02_nested_queries"
    dims = ["QueryWordsCnt"]
    metricks = ["NewClicksFromNested", "Clicks", "Cost", "NewCostFromNested", "Shows"]
    df_chart = df[metricks + dims].groupby("QueryWordsCnt")[metricks].sum()

    df_chart[u"Текущий CTR"] = df_chart["Clicks"] / df_chart["Shows"]
    df_chart[u"Прогнозный CTR"] = (df_chart["Clicks"] + df_chart["NewClicksFromNested"]) / df_chart["Shows"]
    df_chart[u"Изменение CTR"] = (df_chart[u"Прогнозный CTR"] / df_chart[u"Текущий CTR"]) - 1
    df_chart[u"Изменение CTR"] = df_chart[u"Изменение CTR"]

    df_chart[u"Текущая CPC"] = df_chart["Cost"] / df_chart["Clicks"]
    df_chart[u"Прогнозная CPC"] = (df_chart["Cost"] + df_chart["NewCostFromNested"]) / (
        df_chart["Clicks"] + df_chart["NewClicksFromNested"])
    df_chart[u"Изменение CPC"] = (df_chart[u"Прогнозная CPC"] / df_chart[u"Текущая CPC"]) - 1
    df_chart[u"Изменение CPC"] = df_chart[u"Изменение CPC"]

    df_chart.index.rename(u"Кол-во слов", inplace=True)

    cols = [u"Текущий CTR", u"Прогнозный CTR", u"Текущая CPC", u"Прогнозная CPC",
            u"Изменение CTR", u"Изменение CPC"]

    #  на случай когда не все длины есть
    #  от 1, чтобы показать, где улучшения нет.
    #  Иначе график вводит в заблуждение и кажется, что рекламодатель не показывался по какой-то из длин.
    try:
        df_chart = df_chart[cols].round(4).loc[range(1, 8)].fillna(0)
        setattr(df_chart, "formats", {u"Текущий CTR": "percent",
                                      u"Прогнозный CTR": "percent",
                                      u"Текущая CPC": "float",
                                      u"Прогнозная CPC": "float",
                                      u"Изменение CTR": "gain",
                                      u"Изменение CPC": "gain"})
        return df_chart
    except KeyError:
        return None


def top_queries_phrases_from_nested(df):
    "02_nested_queries"

    cols = ["Query", "PhraseText",
            "QueryWordsCnt", "PhraseWordsCnt",
            "NewClicksFromNested"]
    df_chart = (df.loc[
        df["QueryWordsCnt"] > df["PhraseWordsCnt"],
        cols]
        .sort_values("NewClicksFromNested", ascending=False))

    if df_chart.shape[0] == 0:
        return None

    df_chart = (df_chart.groupby(
        ["Query", "PhraseText"],
        as_index=False)
        .agg({"NewClicksFromNested": pd.np.sum})
        .sort_values("NewClicksFromNested", ascending=False)
        .head(20))

    df_chart.rename(columns={
        "Query": u"Поисковый запрос",
        "PhraseText": u"Ключевая фраза",
        "NewClicksFromNested": u"Добавленные клики",
    }, inplace=True)
    col_ord = [u"Поисковый запрос", u"Ключевая фраза", u"Добавленные клики"]
    df_chart = df_chart.loc[:, col_ord]
    setattr(df_chart, "formats", {u"Поисковый запрос": "string",
                                  u"Ключевая фраза": "string",
                                  u"Добавленные клики": "int"})

    return df_chart


def top_queries_from_nested(df):
    "02_top_nested_queries"

    cols = ["CampaignID", "CampaignName", "DirectBannerID", "Query",
            "PhraseText", "QueryWordsCnt", "PhraseWordsCnt",
            "Shows", "Clicks", "Cost",
            "NewClicksFromNested", "NewCPCFromNested", "NewCostFromNested"]
    df_chart = (df.loc[
        df["QueryWordsCnt"] > df["PhraseWordsCnt"],
        cols]
        .sort_values("NewClicksFromNested", ascending=False)
        .head(EXCEL_MAX_ROWS))

    if df_chart.shape[0] == 0:
        return None

    df_chart.rename(columns={
        "CampaignID": u"Кампания №",
        "CampaignName": u"Кампания",
        "DirectBannerID": u"Баннер №",
        "Query": u"Запрос",
        "PhraseText": u"Условие показа",
        "QueryWordsCnt": u"Длина запроса",
        "PhraseWordsCnt": u"Длина условия показа",
        "Shows": u"Показы",
        "Clicks": u"Клики",
        "Cost": u"Расходы",
        "NewClicksFromNested": u"Новые клики",
        "NewCostFromNested": u"Новые расходы"
    }, inplace=True)
    col_ord = [u"Кампания №", u"Кампания", u"Баннер №", u"Запрос",
               u"Условие показа", u"Длина запроса", u"Длина условия показа",
               u"Показы", u"Клики", u"Расходы",
               u"Новые клики", u"Новые расходы"]
    df_chart = df_chart.loc[:, col_ord]

    setattr(df_chart, "formats", {u"Кампания №": "string",
                                  u"Кампания": "string",
                                  u"Баннер №": "string",
                                  u"Запрос": "string",
                                  u"Условие показа": "string",
                                  u"Длина запроса": "int",
                                  u"Длина условия показа": "int",
                                  u"Показы": "int",
                                  u"Клики": "int",
                                  u"Расходы": "float",
                                  u"Новые клики": "int",
                                  u"Новые расходы": "float"})

    return df_chart
