# -*- coding: utf-8 -*-
from copy import deepcopy
import pandas as pd
from benchmarking import calculate_bench_table, calculate_yoy_table
from grouped_tables import calculate_grouped_table, calculate_rating, prepare_grouped_table
from utils import fill_client_comp_columns, fill_with_dashes, filter_by_date


def standard_bench_tables(task, data_df, *opt):
    column, params = opt
    formula = params.get('formula')

    cols = [formula['divinded'], formula['devider']] if formula else [column]
    for col in task.filter_by.values():
        if col not in cols:
            cols.append(col)

    data_df = (data_df.loc[:, ['Date', 'Client', 'Place', 'Device'] + cols].copy()
               .groupby(['Date', 'Client', 'Place', 'Device'], as_index=False)
               .sum()
               )
    data_df = fill_client_comp_columns(task.client, data_df, cols)

    tables, dyn_tables = [], []
    target_columns = []
    for prefix, place, target_col_num in zip(['Total', 'Search', 'Networks'],
                                             [None, [u'Поиск'], [u'Сети']],
                                             [12, 17, 22]):
        tmp_data_df = data_df[data_df['Place'].isin(place)] if place else data_df.copy()

        for i, fn in enumerate([calculate_bench_table, calculate_yoy_table], 1):
            df = fn(task, tmp_data_df.copy(), column, formula)

            if i == 1:
                df = df.rename(columns={
                    'Client%s' % column: '%sClient%s' % (prefix, column),
                    'Comp%s' % column: '%sComp%s' % (prefix, column)})
                target_columns += ['%sClient%s' % (prefix, column), '%sComp%s' % (prefix, column)]
                dyn_tables.append(df)

            elif i == 2:
                setattr(df, 'descr', {
                    'position': {'row': 4, 'column': target_col_num},
                    'columns': ['Period', 'Client%s' % column, 'Comp%s' % column]
                })
                tables.append(df)

        df = calculate_grouped_table(task, tmp_data_df.copy(), *opt, group_by='Device')[0]
        descr = {
            'position': {'row': 9, 'column': target_col_num},
            'columns': ['Device', 'Client%s' % column, 'Comp%s' % column, 'CompSum'] if formula is None else
                       ['Device', 'Client%s' % column, 'Comp%s' % column]
        }
        setattr(df, 'descr', descr)
        tables.append(df)

        if column in ['CR', 'CPA']:
            notes_df = fill_with_dashes(task, df.copy(), column)
            setattr(notes_df, 'descr', {
                'position': {'row': 11, 'column': target_col_num},
                'columns': ['Device', 'Client%s' % column, 'Comp%s' % column]
            })
            tables.append(notes_df)

    df = pd.concat([df_.set_index([u'Date', u'PrettyDate']) for df_ in dyn_tables], axis='columns').reset_index()
    setattr(df, 'descr', {
        'position': {'row': 4, 'column': 1},
        'columns': [u'Date', u'PrettyDate'] + target_columns
    })
    tables.append(df)

    return tables


def standard_types_sheets(task, data_df, *opt):
    column, params = opt
    formula = params.get('formula')
    cols = [formula['divinded'], formula['devider']] if formula else [column]

    data_df = fill_client_comp_columns(task.client, data_df.copy(), cols)

    tables = []
    for table in task.config['tables']:
        group_by = table.get('group_by')
        df = calculate_grouped_table(task, data_df, *opt, group_by=group_by, place=table.get('Place'))[0]
        df = prepare_grouped_table(df, column, formula, group_by, group_names=table.get('group_names'))

        descr = get_types_table_meta(column, formula, group_by, table)
        setattr(df, 'descr', descr)
        tables.append(df)

        if column in ['CR', 'CPA']:
            notes_df = fill_with_dashes(task, df.copy(), column)

            notes_descr = deepcopy(descr)
            if group_by == 'Place':
                notes_descr['position']['column'] += 4
            else:
                notes_descr['position']['row'] += 42

            setattr(notes_df, 'descr', notes_descr)
            tables.append(notes_df)

    group_by = 'TargetingType'
    for banner_type, row_num in zip([u'Текстово-графические', u'Графические', u'Смарт-баннеры'],
                                    [19, 21, 23]):
        df = data_df.loc[data_df.BannerType.isin([banner_type])]
        df = calculate_grouped_table(task, df, *opt, group_by=group_by, place=u'Сети')[0]
        df = prepare_grouped_table(df, column, formula, group_by)

        columns = [group_by, 'Client%s' % column, 'Comp%s' % column]
        if not formula:
            columns += ['CompSum', 'ClientShares', 'CompShares']
        descr = {'position': {'row': row_num, 'column': 2},
                 'columns': columns}
        setattr(df, 'descr', descr)
        tables.append(df)

        if column in ['CR', 'CPA']:
            notes_df = fill_with_dashes(task, df.copy(), column)
            setattr(notes_df, 'descr', {'position': {'row': row_num + 42, 'column': 2},
                                        'columns': [group_by, 'Client%s' % column, 'Comp%s' % column]})
            tables.append(notes_df)

    return tables


def get_types_table_meta(column, formula, group_by, table):
    descr = deepcopy(table.get('descr'))
    descr['columns'] = [group_by, 'Client%s' % column, 'Comp%s' % column]
    if not formula:
        descr['columns'] += ['CompSum', 'ClientShares', 'CompShares']
    if table.get('group_names'):
        descr['columns'].insert(1, '%s_2' % group_by)
    return descr


def standard_competitors_sheet(task, data_df):
    df = calculate_rating(task, filter_by_date(data_df.copy(), task.periods['period_2']))
    setattr(df, 'descr', {
        'position': {'row': 3, 'column': 1},
        'columns': ['Client', task.target, 'DirectCost', 'CPA']})

    return df
