# -*- coding: utf-8 -*-
import logging
import pandas as pd
import requests
from StringIO import StringIO
from time import sleep

from weekly_pack.data import SECRET
from proceed_data import get_occ_query, round_date, write_table
from yql_workers import get_query_text

logger = logging.getLogger(__name__)


def restartable(retries=2, pause=60):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for try_ in xrange(retries):
                try:
                    return func(*args, **kwargs)
                except KeyboardInterrupt as kb_exception:
                    raise kb_exception
                except Exception as exc:
                    logger.warning('An exception occurred at attempt #{}'.format(try_))
                    logger.warning(exc.message)
                    logger.warning('Restarting in {} seconds...'.format(pause))
                    sleep(pause)
                    continue
            raise Exception('Max retries has been reached ({})'.format(retries))
        return wrapper
    return decorator


# @restartable(retries=10, pause=60)
def april_data(period):
    logger.info('April_data')

    request = requests.post(
        'http://april-storage01i.yandex.ru:8123',
        data=get_query_text('artmon').replace('{from_dt}', period['from_dt']).replace('{to_dt}', period['to_dt']),
        timeout=60,
        params={'user': 'readonly'}
    )
    if request.status_code != 200:
        raise Exception(request.text.strip())

    header = ['week', 'place', 'device', 'geo', 'hits', 'shows', 'clicks', 'cost', 'prgmg', 'installs']
    df = pd.read_csv(StringIO(request.text), sep='\t', names=header)

    df['device'] = df['device'].replace({'Desktop': u'Десктоп', 'Mobile': u'Мобильные устройства'})
    df['geo'] = df['geo'].replace({
        'Moscow': u'Москва и Московская область',
        'Saint-Petersburg': u'Санкт-Петербург и Ленинградская область',
        'Regions': u'Остальная Россия',
        'World': u'Остальной мир'
    })
    df = df.sort_values(['week', 'place', 'device', 'geo'])
    write_table(
        '//home/vipplanners/weekly_pack/artmon',
        [
            {'name': 'week', 'type': 'string'},
            {'name': 'place', 'type': 'string'},
            {'name': 'device', 'type': 'string'},
            {'name': 'geo', 'type': 'string'},
            {'name': 'hits', 'type': 'int64'},
            {'name': 'shows', 'type': 'int64'},
            {'name': 'clicks', 'type': 'int64'},
            {'name': 'cost', 'type': 'double'},
            {'name': 'prgmg', 'type': 'double'},
            {'name': 'installs', 'type': 'int64'}
        ],
        df
    )
    df = df.rename(columns={
        'week': u'Неделя',
        'place': u'Площадка',
        'device': u'Устройство',
        'geo': u'Регион',
        'hits': u'Хиты',
        'shows': u'Показы',
        'clicks': u'Клики',
        'cost': u'Открутки',
        'prgmg': u'Конверсии',
        'installs': u'Установки'
    })

    return df


# @restartable(retries=10, pause=60)
def one_cent_clicks_by_type(query, type_, ru_type):
    request = requests.get(query, headers={'Authorization': 'OAuth ' + SECRET['artmon_token']}, verify=False)

    res = request.text.split('\n')
    header = res[0].strip(u'\ufeff').split('\t')
    cols_ids = {'dt': None, 'name': None, 'clicks_set': None, 'clicks_paid': None}
    for i in xrange(0, len(header)):
        if header[i].startswith(u'Время'):
            cols_ids['dt'] = i
        elif header[i].startswith(u'series'):
            cols_ids['name'] = i
        elif header[i].startswith(u'Клики, {}, абсолютное значение, Выставленная'.format(ru_type)):
            cols_ids['clicks_set'] = i
        elif header[i].startswith(u'Клики, {}, абсолютное значение, Списанная'.format(ru_type)):
            cols_ids['clicks_paid'] = i

    data = {}
    for i, line in enumerate(res[1:]):
        values = line.split('\t')
        data[i] = {
            'dt': values[cols_ids['dt']][:10] if cols_ids['dt'] == cols_ids['dt'] else None,
            'name': values[cols_ids['name']] if cols_ids['name'] else None,
            'clicks_set': int(values[cols_ids['clicks_set']]) if cols_ids['clicks_set'] else None,
            'clicks_paid': int(values[cols_ids['clicks_paid']]) if cols_ids['clicks_paid'] else None
        }
    df = pd.DataFrame(data).T
    df['type'] = type_

    return df


def one_cent_clicks(period):
    logger.info('One_cent_clicks')

    types = ['all', 'search mob all_ads_page', 'context_net']
    ru_types = [u'Все площадки', u'Большой поиск + Мобильный поиск + Страница "Все объявления"', u'- Контекстная сеть']
    df = pd.DataFrame()
    for type_, ru_type in zip(types, ru_types):
        tmp_df = one_cent_clicks_by_type(get_occ_query(type_, period['from_dt'], period['to_dt']), type_, ru_type)
        df = tmp_df if df.empty else pd.concat([df, tmp_df])

    df['type'] = df['type'].replace({
        'all': u'Все площадки',
        'search mob all_ads_page': u'Поиск',
        'context_net': u'Контекстная сеть'
    })
    df['new_name'] = df['name'].replace({u'2 - 10 центов': u'< 10 центов', u'1 цент': u'< 10 центов'})
    df['week'] = df['dt'].apply(round_date)

    df = df[['dt', 'week', 'type', 'name', 'new_name', 'clicks_set', 'clicks_paid']].reset_index(drop=True)

    df = df.rename(columns={
        'dt': u'День',
        'week': u'Неделя',
        'type': u'Площадка',
        'name': u'Цена',
        'new_name': u'Цена_2',
        'clicks_set': u'Клики, выставленная',
        'clicks_paid': u'Клики, списанная'
    })

    return df
