# -*- coding: utf-8 -*-
import logging
from os.path import dirname, join

from exceller.cell import Cell
from exceller import ExcelDocument
from calculations.fin_tables import (
    create_bench_tables_by_places,
    fin_competitors_sheet,
    fin_target_share_dynamics,
    fin_types_sheet,
    fin_overview_sheet,
    categories_sheet
)
from calculations.utils import get_gain
from cpa_task.utils import convert_name
from xlsx_worker import fill_info_ws, format_charts, get_range_addr, get_last_cell_hor, rng_formula_to_address, write_df

logger = logging.getLogger(__name__)


def finance_report(task, df, region, category, **kwargs):
    report_name = u'{f_num}_{client}_{region}_{cat}.xlsx'.format(
        f_num=kwargs.get('f_num'), client=task.client, region=region['region_name'], cat=category)
    report_path = join(dirname(dirname(__file__)), report_name)
    logger.info(u'%s: make %s' % (task.issue.key, report_name))

    report = ExcelDocument(join(dirname(dirname(__file__)), 'templates', task.config['xlsx_template']))
    report = finance_template_cleaner(report)

    write_df(report[u'Сводка'], fin_overview_sheet(task, df))
    for metric, params in task.calculations.iteritems():
        if type(params['sheet_pref']) != unicode:
            params['sheet_pref'] = params['sheet_pref'].decode('utf-8')

        ws = report[params['sheet_pref']]
        for res in create_bench_tables_by_places(task, df, metric, params):
            write_df(ws, res)
        fill_formula_cells(task.client, ws, fin_get_named_rages(params.get('rng_pref', metric)))

        if params['sheet_pref'] != 'CPC':
            ws = report[u'{} (типы)'.format(params['sheet_pref'])]
            for res in fin_types_sheet(task, df, metric, params):
                write_df(ws, res)
            for addr in ['C2', 'C8', 'M8']:
                ws[addr].text = task.client

    fill_competitors_sum_sheet(task, df, report[u'Конкуренты (сумма)'])
    fill_target_share_sheets(report, task, df)
    fill_categories_sheet(task, df, report[u'Категории'])

    info = {'B9': convert_name(task.target, task.config['Targets'], to_local=False),
            'B15': task.client,
            'B20': category,
            'M4': region['region_name'],
            'B26': task.time_detail,
            'B31': task.period['first_date'].strftime('%Y-%m-%d'),
            'D31': task.period['last_date'].strftime('%Y-%m-%d'),

            'B36': task.periods['period_1']['first_date'].strftime('%Y-%m-%d'),
            'C36': task.periods['period_1']['last_date'].strftime('%Y-%m-%d'),

            'D36': task.periods['period_2']['first_date'].strftime('%Y-%m-%d'),
            'E36': task.periods['period_2']['last_date'].strftime('%Y-%m-%d'),

            'B42': task.attribution,
            'B47': task.currency,
            'B52': task.vat
            }
    fill_info_ws(report['Info'], task, info, region)

    if task.format_charts:
        format_charts(report, task.config['charts'])

    report.update_charts_cache(named_to_simple_ranges=True)
    report.save(report_path)

    return report_path


def fill_competitors_sum_sheet(task, df, ws):
    for res in fin_competitors_sheet(task, df):
        ws = write_df(ws, res)

    for prefix, p1_col_num, p2_col_num in zip(['', '_Search', '_Networks'], [1, 4, 7], [12, 19, 26]):
        rng_formula_to_address(
            ws, [u'Period1_Clients%s' % prefix, u'Period1_Target%s' % prefix], [p1_col_num, p1_col_num + 1], 4)
        rng_formula_to_address(
            ws, [u'Period2_Clients%s' % prefix, u'Period2_Target%s' % prefix], [p2_col_num, p2_col_num + 2], 4)

        rng_formula_to_address(
            ws, [u'Period2_Comp_Target%s' % prefix, u'Period2_Comp_CPA%s' % prefix, u'Period2_Comp_CR%s' % prefix],
            [p2_col_num + 2, p2_col_num + 4, p2_col_num + 5], 5)

    return ws


def fill_target_share_sheets(report, task, df):
    for place in [None, [u'Поиск'], [u'Сети']]:
        ws_name = u'Доля конверсий ({})'.format(place[0].lower()) if place else u'Доля конверсий'
        ws = report[ws_name]

        write_df(ws, fin_target_share_dynamics(task, df, place))
        update_dynamics(ws)

    return report


def fill_categories_sheet(task, df, ws):
    ws = write_df(ws, categories_sheet(task, df))
    rng_formula_to_address(
        ws, [u'Categories', u'Category_Clicks', u'Category_Target', u'Category_Cost'], range(1, 5), 3)

    return ws


def fin_get_named_rages(rng_pref):
    rngs = [u'Periods',
            u'Client', u'Comp', u'Min', u'Max',
            u'Client_Search', u'Comp_Search', u'Min_Search', u'Max_Search',
            u'Client_Networks', u'Comp_Networks', u'Min_Networks', u'Max_Networks',
            ]
    rngs = [u'{}_{}'.format(rng_pref, x) for x in rngs]

    return rngs


def finance_template_cleaner(report):
    for ws in report:
        if ws.name == 'Info':
            for row in [9, 15, 20, 26, 31, 36, 42, 47, 52]:
                ws.clear_value('B{0}:E{0}'.format(row))
            ws.clear_value('M4:N5')

        elif u'типы' in ws.name:
            for rng in ['C2', 'C8', 'M8', 'C3:G4', 'C9:G13', 'M9:Q14']:
                rng = '{0}:{0}'.format(rng) if ':' not in rng else rng
                ws.clear_contents(rng)
            for rng in ['B3:B4', 'B9:B13', 'L9:L14']:
                ws.clear_value(rng)

        elif ws.name == u'Конкуренты (сумма)':
            ws.clear_contents('A4:AE25')
            ws.clear_value('A4:AE25')

        elif u'Доля конверсий' in ws.name:
            ws.clear_contents('A2:AG17')
            ws.clear_value('A2:AG17')

        elif ws.name == u'Категории':
            ws.clear_contents('A3:D10')
            ws.clear_value('A3:D10')

        elif ws.name == u'Сводка':
            ws.clear_contents('A4:H11')
            ws.clear_value('A4:H11')

        else:
            for rng in ['C3', 'G3', 'K3', 'S3', 'S8', 'S15', 'S20', 'S27', 'S32', 'C4:N18', 'R4:W6', 'S9:U10',
                        'R16:W18', 'S21:U22', 'R28:W30', 'S33:U34']:
                rng = '{0}:{0}'.format(rng) if ':' not in rng else rng
                ws.clear_contents(rng)
            for rng in ['A4:B18', 'R9:R10', 'R21:R22', 'R33:R34']:
                ws.clear_value(rng)

    return report


def fill_formula_cells(client, ws, rngs):
    ws = rng_formula_to_address(ws, rngs, range(2, 15), 4)
    for addr in ['C3', 'G3', 'K3', 'S3', 'S8', 'S15', 'S20', 'S27', 'S32']:
        ws[addr].text = client
    ws = write_fin_gains(ws)
    return ws


def write_fin_gains(ws):
    for row_num in [6, 18, 30]:
        row_1, row_2 = row_num - 2, row_num - 1

        ws.set_cell_value(row_num, 19, get_gain(ws['S%i' % row_2], ws['S%i' % row_1], format_=u'{:+,.1%}'))
        ws.set_cell_value(row_num, 20, get_gain(ws['T%i' % row_2], ws['T%i' % row_1], format_=u'{:+,.1%}'))
        ws.set_cell_value(row_2, 23, get_gain(ws['S%i' % row_2], ws['T%i' % row_2], format_=u'{:+,.1%}'))

    return ws


def update_dynamics(ws):
    chart = ws.charts[u'Dynamics']

    x_vals = get_range_addr(ws, 3, 2)
    lc = get_last_cell_hor(ws, 2, 1)
    s_cnt = lc.col_index - 2

    chart.set_series_count(s_cnt)

    for col, series in enumerate(chart.series, 3):
        series.name = u"'%s'!%s2" % (ws.name, Cell.column_to_letter(col))
        series.cat_ref.f = x_vals
        series.val_ref.f = get_range_addr(ws, 3, col)

    return ws
