# -*- coding: utf-8 -*-
import logging
from datetime import datetime as dt
from dateutil.rrule import rrule, DAILY, WEEKLY, MONTHLY
import pandas as pd
from templates import read_yml_config

logger = logging.getLogger(__name__)
DICTS = read_yml_config('dicts.yml')


def prepare_category_df(task, region, category):
    df = task.df.copy()
    if task.type_ in ['retail', 'finance'] and category == u'Суммарные данные':
        return df[df['Regions'].isin([region['region_ids']])]
    else:
        return df[df['Category'].isin([category]) & df['Regions'].isin([region['region_ids']])]


def filter_by_date(df, period):
    return df[(df['Date'] >= period['first_date']) & (df['Date'] <= period['last_date'])]


def fill_client_comp_columns(client, df, cols):
    for col in cols:
        try:
            df['Client%s' % col] = df.apply(lambda df_: df_[col] if df_['Client'] == client else pd.np.nan, axis=1)
        except Exception:
            df['Client%s' % col] = pd.np.nan

        try:
            df['Comp%s' % col] = df.apply(lambda df_: df_[col] if df_['Client'] != client else pd.np.nan, axis=1)
        except Exception:
            df['Comp%s' % col] = pd.np.nan

    return df


def calculate_shares(df, column):

    df['ClientShares'] = df['Client%s' % column] / df['Client%s' % column].sum()
    df['CompShares'] = df['CompSum'] / df['CompSum'].sum()

    for col_name in ['ClientShares', 'CompShares']:
        df[col_name] = df[col_name].fillna(0)
        sum_ = sum([round(val * 100) for val in df[col_name].values])
        if sum_ == 0 or sum_ == 100:
            df[col_name] = df[col_name].apply(lambda cell: u'{:.0%}'.format(float(cell)).replace('.', ','))
        else:
            df[col_name] = df[col_name].apply(lambda cell: u'{:.1%}'.format(float(cell)).replace('.', ','))

    return df.fillna(0)


def fill_with_dashes(task, df, column):
    if column == 'CPA':
        format_ = u'{:,.0f}'
        df['Client%s' % column] = df.apply(
            lambda row: u'—'
            if row['Client%s' % task.filter_by['Clicks']] >= 0 and row['Client%s' % task.filter_by['Conversions']] == 0
            else format_.format(row['Client%s' % column]).replace(',', ' ').replace('.', ','),
            axis=1
        )
        df['Comp%s' % column] = df.apply(
            lambda row: u'—'
            if row['Comp%s' % task.filter_by['Clicks']] >= 0 and row['Comp%s' % task.filter_by['Conversions']] == 0
            else format_.format(row['Comp%s' % column]).replace(',', ' ').replace('.', ','),
            axis=1
        )
    elif column == 'CR':
        format_ = u'{:.1%}'
        df['Client%s' % column] = df.apply(
            lambda row: u'—'
            if row['Client%s' % task.filter_by['Clicks']] == 0 and row['Client%s' % task.filter_by['Conversions']] >= 0
            else format_.format(row['Client%s' % column]).replace(',', ' ').replace('.', ','),
            axis=1
        )
        df['Comp%s' % column] = df.apply(
            lambda row: u'—'
            if row['Comp%s' % task.filter_by['Clicks']] == 0 and row['Comp%s' % task.filter_by['Conversions']] >= 0
            else format_.format(row['Comp%s' % column]).replace(',', ' ').replace('.', ','),
            axis=1
        )

    return df


def fill_empty_df(data, group_by=None):
    df = pd.DataFrame(data)
    if group_by:
        df = df.groupby(group_by, as_index=True).sum()
    return df


def fill_missed_dates(task, df):
    cur_periods = df['Date'].values.tolist()
    cur_periods = [dt.utcfromtimestamp(date / 1e9) for date in cur_periods] if cur_periods else []

    new_row = {}
    for col in df.columns:
        new_row[col] = [pd.np.nan]

    all_dates = [pd.np.datetime64(date) for date in get_all_dates(task.time_detail, task.period)]
    for date in all_dates:
        if date not in cur_periods:
            new_row['Date'] = [pd.np.datetime64(date)]
            try:
                df = df.append(pd.DataFrame(new_row))
            except Exception:
                df = pd.DataFrame(new_row)

    return df.sort_values(by='Date').reset_index(drop=True)


def get_all_dates(time_detail, period):
    if time_detail == u'Дни':
        return rrule(DAILY, dtstart=period['first_date'], until=period['last_date'])

    elif time_detail == u'Недели':
        return rrule(WEEKLY, dtstart=period['first_date'], until=period['last_date'])

    elif time_detail == u'Месяцы':
        return rrule(MONTHLY, dtstart=period['first_date'], until=period['last_date'])


def get_gain(cell1, cell2, format_=None):
    gain = 0

    v1, v2 = to_float(cell1.text), to_float(cell2.text)
    if v2 != 0:
        gain = (v1 / v2) - 1

    if gain == 0:
        format_ = u'{:,.0%}'
    else:
        format_ = u'{:+,.1%}' if abs(gain) < 0.01 else u'{:+,.0%}'
    gain = format_.format(gain) if gain > 0 else format_.replace('+', '').format(gain)

    if v2 == 0:
        gain = u''
    return gain.replace(',', ' ').replace('.', ',')


def to_float(value):
    try:
        if value == u'—':
            return value
        else:
            return float(value)
    except ValueError:
        return 0.0
