# -*- coding: utf-8 -*-
from copy import deepcopy
from datetime import datetime
import logging
import pandas as pd
import statface_client

from weekly_pack.data import CONFIG, SECRET
from proceed_data import (
    flat_table_by_devices,
    get_cluster_name,
    get_cluster_shifted_value,
    get_other_adv,
    get_shifted_value,
    round_date,
    write_table
)

cli = statface_client.StatfaceClient(
    oauth_token=SECRET['token'],
    host=statface_client.STATFACE_PRODUCTION
)

logger = logging.getLogger(__name__)


def get_stat_data(config_name, week_sum=True):
    logger.info('Stat: %s' % config_name)

    config = deepcopy(CONFIG[config_name])
    config['params'].update({
        'date_min': '2019-02-11',
        'date_max': datetime.today().strftime('%Y-%m-%d')
    })

    report = cli.get_report(config['path'])
    report_data = report.download_data(**config['params'])
    report_data = pd.DataFrame(report_data)[config['columns'].keys()].rename(columns=config['columns'])

    if 'adv' in config['columns'].values():
        report_data['adv'] = report_data['adv'].replace({
            u'Google Ads': u'Google',
            u'Яндекс': u'Яндекс'
        })
    if 'device' in config['columns'].values():
        report_data['device'] = report_data['device'].replace({u'Телефоны+планшеты': u'Мобильные устройства'})
    if 'place' in config['columns'].values():
        report_data['place'] = report_data['place'].replace({
            u'Поисковые визиты': u'Поиск',
            u'Непоисковые визиты': u'Сети'
        })

    if week_sum:
        report_data['dt'] = report_data['dt'].apply(round_date)
    else:
        report_data['dt'] = report_data['dt'].apply(lambda cell: str(cell)[:10])

    return report_data


def get_traffic_data(report_data):
    report_data = report_data[
        report_data['adv'].isin([u'Всего', u'Google', u'Яндекс']) &
        report_data['place'].isin([u'Поиск', u'Сети']) &
        report_data['device'].isin([u'Всего', u'Десктоп', u'Мобильные устройства'])
    ]
    report_data = pd.DataFrame(report_data.groupby(['dt', 'adv', 'place', 'device', 'os'], as_index=False).sum())
    df = flat_table_by_devices(report_data.copy(), 'traffic')
    result_df = pd.concat([
        get_other_adv(df, 'traffic'),
        df[~df['adv'].isin([u'Всего'])]
    ]).reset_index(drop=True)

    return result_df


def get_searches_data(report_data):
    report_data['place'] = u'Поиск'
    report_data = report_data[
        report_data['adv'].isin([u'Всего', u'Google', u'Яндекс']) &
        report_data['device'].isin([u'Всего', u'Десктоп', u'Мобильные устройства']) &
        report_data['os'].isin([u'Android', u'iOS', u'Всего'])
    ]
    report_data = pd.DataFrame(report_data.groupby(['dt', 'adv', 'place', 'device', 'os'], as_index=False).sum())

    df = flat_table_by_devices(report_data.copy(), 'searches')
    result_df = pd.concat([
        get_other_adv(df, 'searches'),
        df[~df['adv'].isin([u'Всего'])]
    ]).reset_index(drop=True)

    return result_df


def get_shares():
    traffic_df = get_traffic_data(get_stat_data('traffic'))
    searches_df = get_searches_data(get_stat_data('searches'))

    group_cols = ['dt', 'adv', 'place', 'device', 'os']
    result_df = traffic_df.merge(
        searches_df.drop_duplicates(subset=group_cols),
        how='left', left_on=group_cols, right_on=group_cols, suffixes=('', '_search')
    )

    result_df['prev_traffic'] = result_df.apply(lambda row: get_shifted_value(row, result_df, 'traffic'), axis=1)
    result_df['prev_searches'] = result_df.apply(lambda row: get_shifted_value(row, result_df, 'searches'), axis=1)

    result_df = result_df.sort_values(group_cols)[group_cols + ['traffic', 'prev_traffic', 'searches', 'prev_searches']]
    write_table(
        '//home/vipplanners/weekly_pack/shares',
        [
            {'name': 'dt', 'type': 'string'},
            {'name': 'adv', 'type': 'string'},
            {'name': 'place', 'type': 'string'},
            {'name': 'device', 'type': 'string'},
            {'name': 'os', 'type': 'string'},
            {'name': 'traffic', 'type': 'double'},
            {'name': 'prev_traffic', 'type': 'double'},
            {'name': 'searches', 'type': 'double'},
            {'name': 'prev_searches', 'type': 'double'}
        ],
        result_df
    )
    result_df = result_df.rename(columns={
        'dt': u'Неделя',
        'adv': u'Поисковая система',
        'place': u'Площадка',
        'device': u'Устройство',
        'os': u'ОС',
        'traffic': u'Рекламные визиты',
        'prev_traffic': u'Рекламные визиты YoY',
        'searches': u'Поисковые переходы',
        'prev_searches': u'Поисковые переходы YoY',
    })

    return result_df


def get_clusters():
    report_data = get_stat_data('clusters')

    report_data = report_data[~report_data['group'].isin([u'Total without unclustered', u'Total'])]
    report_data = pd.DataFrame(report_data.groupby(['dt', 'group', 'scenario'], as_index=False).sum())

    report_data['forecast'] = report_data.apply(
        lambda row: row['revenue'] if row['scenario'] == 'pessimistic' else 0, axis=1)
    report_data['fact'] = report_data.apply(
        lambda row: row['revenue'] if row['scenario'] == 'fact' else 0, axis=1)

    report_data = pd.DataFrame(
        report_data[['dt', 'group', 'forecast', 'fact']].groupby(['dt', 'group'], as_index=False).sum()
    )
    report_data['prev_fact'] = report_data.apply(
        lambda row: get_cluster_shifted_value(row, report_data, 'fact'), axis=1)
    report_data['cluster'] = report_data['group'].apply(get_cluster_name)

    group_cols = ['dt', 'cluster', 'group']
    report_data = report_data.sort_values(group_cols)[group_cols + ['forecast', 'fact', 'prev_fact']]
    write_table(
        '//home/vipplanners/weekly_pack/clusters',
        [
            {'name': 'dt', 'type': 'string'},
            {'name': 'cluster', 'type': 'string'},
            {'name': 'group', 'type': 'string'},
            {'name': 'forecast', 'type': 'double'},
            {'name': 'fact', 'type': 'double'},
            {'name': 'prev_fact', 'type': 'double'}
        ],
        report_data
    )
    report_data = report_data.rename(columns={
        'dt': u'Неделя',
        'cluster': u'Кластер',
        'group': u'Группа',
        'forecast': u'Прогноз откруток',
        'fact': u'Открутки',
        'prev_fact': u'Открутки YoY'
    })

    return report_data


def get_potential():
    report_data = get_stat_data('potential', week_sum=False)

    report_data['balance'] = report_data.apply(
        lambda row: row['value'] if row['type'] == 'Balance' else 0, axis=1)
    report_data['potential'] = report_data.apply(
        lambda row: row['value'] if row['type'] == 'Potential' else 0, axis=1)
    report_data['revenue'] = report_data.apply(
        lambda row: row['value'] if row['type'] == 'Revenue' else 0, axis=1)

    report_data = pd.DataFrame(
        report_data[['dt', 'balance', 'potential', 'revenue']].groupby(['dt'], as_index=False).sum()
    ).sort_values('dt')
    report_data['week'] = report_data['dt'].apply(round_date)
    report_data['potential_share'] = report_data['potential'] / report_data['balance']
    report_data['revenue_share'] = report_data['revenue'] / report_data['potential']

    report_data = pd.DataFrame(
        report_data[['week', 'balance', 'potential', 'revenue', 'potential_share', 'revenue_share']]
        .groupby(['week'], as_index=False).mean()
    )
    write_table(
        '//home/vipplanners/weekly_pack/potential',
        [
            {'name': 'week', 'type': 'string'},
            {'name': 'balance', 'type': 'double'},
            {'name': 'potential', 'type': 'double'},
            {'name': 'revenue', 'type': 'double'},
            {'name': 'potential_share', 'type': 'double'},
            {'name': 'revenue_share', 'type': 'double'}
        ],
        report_data
    )
    report_data = report_data.rename(columns={
        'week': u'Неделя',
        'balance': u'Баланс',
        'potential': u'Потенциал',
        'revenue': u'Выручка',
        'potential_share': u'Доля потенциала от баланса',
        'revenue_share': u'Доля выручки от потенциала',
    })

    return report_data
