# coding: utf-8
"""xlsx-keywords:
- 12_group_banners_count
- 12_group_just_one_banner
- 12_group_phrases_count
- 12_group_just_one_phrase
"""
from hashlib import md5

from ..review import Recommendation, append_recommendation
from ..const import EXCEL_MAX_ROWS
from ..utils import (
    get_group_url,
    get_cid
)


def table_group_banners_count(df, normalize):
    """12_group_banners_count"""
    MAX_COUNT = 3
    df_chart = (
        df.assign(
            BannerText=lambda df: (df.Title + df.Body).apply(lambda x: md5(x.encode("u8")).hexdigest()))
        .groupby("GroupID")
        .agg(
            {
                "Shows": sum,
                "Clicks": sum,
                "Cost": sum,
                "BannerText": lambda xs: xs.unique().size})
        .assign(
            GroupType=lambda xf: xf.BannerText.apply(lambda x: min(MAX_COUNT, x)),
            Count=1)
        .groupby("GroupType")
        .agg(
            {
                "Count": sum,
                "Shows": sum,
                "Clicks": sum,
                "Cost": sum}))

    df_chart.rename(columns={
        "Count": u"Кол-во групп",
        "Shows": u"Показы",
        "Clicks": u"Клики",
        "Cost": u"Расходы"},
        inplace=True)
    df_chart.rename(index={
        1: '1',
        2: '2',
        3: u"3 и более"},
        inplace=True)
    df_chart.index.names = [u"Кол-во объяв. в группе"]
    sum_cols = [u"Кол-во групп", u"Показы", u"Клики", u"Расходы"]

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

    if normalize:
        df_chart.loc[:, sum_cols] = df_chart.loc[:, sum_cols].apply(lambda x: x / x.sum())

        # Лимиты из головы эксперта, можно двигать
        try:
            bad_group_b, bad_group_s = df_chart.loc['1', [u"Кол-во групп", u"Показы"]]
        except KeyError:
            bad_group_b, bad_group_s = 0., 0.
        if bad_group_b > 0.05 or bad_group_s > 0.05:
            Rec = Recommendation(
                dataframe=df,
                internal_sheet_name="12_group_banners_count",
                title=u"Группы объявлений",
                snippet=u"В %.0f%% групп (%.0f%% показов) добавлено одно (или несколько идентичных) объявление" %
                        (bad_group_b * 100., bad_group_s * 100.),
                importance_lvl=2
            )
            append_recommendation(df, Rec)

    df_chart = df_chart.loc[('1', '2', u'3 и более'), sum_cols].fillna(0)

    if normalize:
        formats = {
            u"Кол-во групп": "percent",
            u"Показы": "percent",
            u"Клики": "percent",
            u"Расходы": "percent", }
    else:
        formats = {
            u"Кол-во групп": "int",
            u"Показы": "int",
            u"Клики": "int",
            u"Расходы": "float", }

    setattr(df_chart, "formats", formats)

    return df_chart


def table_group_just_one_banner(df):
    """12_group_just_one_banner"""
    df_chart = (
        df.assign(
            BannerText=lambda df: (df.Title + df.Body).apply(
                lambda x: md5(x.encode("u8")).hexdigest()))
        .groupby("GroupID", as_index=False)
        .agg(
            {
                "BannerText": lambda xs: xs.unique().size,
                "CampaignID": lambda xs: xs.iloc[0],  # like any
                "CampaignName": lambda xs: xs.iloc[0],  # like any
                "GroupName": lambda xs: xs.iloc[0],  # like any
                "Shows": sum,
                "Clicks": sum,
                "Cost": sum
            })
        .query("BannerText == 1 & Shows > 10"))

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

    df_chart = (
        df_chart.sort_values("Shows", ascending=False)
        .head(EXCEL_MAX_ROWS)
        .assign(
            CampaignURL=lambda xf: xf.CampaignID.apply(get_cid),
            GroupURL=lambda xf: xf.apply(
                lambda xr: get_group_url(xr["CampaignID"], xr["GroupID"]), axis=1)
        )
        .loc[:, [
            "CampaignID",
            "CampaignName",
            "GroupID",
            "GroupName",
            "Shows",
            "Clicks",
            "Cost",
            "CampaignURL",
            "GroupURL"
        ]]
    )

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

    df_chart.rename(columns={
        "Shows": u"Показы",
        "Clicks": u"Клики",
        "Cost": u"Расходы",
        "CampaignID": u"Кампания №",
        "CampaignName": u"Название кампании",
        "GroupID": u"Группа №",
        "GroupName": u"Название группы",
        "CampaignURL": u"Ссылка на кампанию",
        "GroupURL": u"Ссылка на группу"},
        inplace=True)

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


def table_group_phrases_count(df, normalize):
    """12_group_phrases_count"""
    MAX_COUNT = 3
    df_chart = (
        df.groupby("GroupID")
        .agg(
            {
                "Shows": sum,
                "Clicks": sum,
                "Cost": sum,
                "DirectPhraseID": lambda xs: xs.unique().size})
        .assign(
            GroupType=lambda xf: xf.DirectPhraseID.apply(
                lambda x: min(MAX_COUNT, x)),
            Count=1)
        .groupby("GroupType")
        .agg(
            {
                "Count": sum,
                "Shows": sum,
                "Clicks": sum,
                "Cost": sum}))

    df_chart.rename(columns={
        "Count": u"Кол-во групп",
        "Shows": u"Показы",
        "Clicks": u"Клики",
        "Cost": u"Расходы"},
        inplace=True)
    df_chart.rename(index={
        1: '1',
        2: '2',
        3: u"3 и более"},
        inplace=True)
    df_chart.index.names = [u"Кол-во фраз. в группе"]
    sum_cols = [u"Кол-во групп", u"Показы", u"Клики", u"Расходы"]

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

    if normalize:
        df_chart.loc[:, sum_cols] = df_chart.loc[:, sum_cols].apply(
            lambda x: x / x.sum())

    df_chart = df_chart.loc[('1', '2', u'3 и более'), sum_cols].fillna(0)

    if normalize:
        formats = {
            u"Кол-во групп": "percent",
            u"Показы": "percent",
            u"Клики": "percent",
            u"Расходы": "percent", }
    else:
        formats = {
            u"Кол-во групп": "int",
            u"Показы": "int",
            u"Клики": "int",
            u"Расходы": "float", }

    setattr(df_chart, "formats", formats)

    return df_chart


def table_group_just_one_phrase(df):
    """12_group_just_one_phrase"""
    df_chart = (
        df.groupby("GroupID", as_index=False)
        .agg(
            {
                "DirectPhraseID": lambda xs: xs.unique().size,
                "CampaignID": lambda xs: xs.iloc[0],  # like any
                "CampaignName": lambda xs: xs.iloc[0],  # like any
                "GroupName": lambda xs: xs.iloc[0],  # like any
                "Shows": sum,
                "Clicks": sum,
                "Cost": sum
            })
        .query("DirectPhraseID == 1 & Shows > 10"))

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

    df_chart = (
        df_chart.sort_values("Shows", ascending=False)
        .head(EXCEL_MAX_ROWS)
        .assign(
            CampaignURL=lambda xf: xf.CampaignID.apply(get_cid),
            GroupURL=lambda xf: xf.apply(lambda xr: get_group_url(xr["CampaignID"], xr["GroupID"]), axis=1)
        )
        .loc[:, [
            "CampaignID",
            "CampaignName",
            "GroupID",
            "GroupName",
            "Shows",
            "Clicks",
            "Cost",
            "CampaignURL",
            "GroupURL"
        ]]
    )

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

    df_chart.rename(columns={
        "Shows": u"Показы",
        "Clicks": u"Клики",
        "Cost": u"Расходы",
        "CampaignID": u"Кампания №",
        "CampaignName": u"Название кампании",
        "GroupID": u"Группа №",
        "GroupName": u"Название группы",
        "CampaignURL": u"Ссылка на кампанию",
        "GroupURL": u"Ссылка на группу"},
        inplace=True)

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