# -*- coding: utf-8 -*-
from collections import OrderedDict
import logging
from os.path import basename, dirname, join
import pandas as pd

from exceller import ExcelDocument
from mks_tables import insert_tables
from pptx import Presentation
from proceed_config import get_pptx_config, split_template_by_titles, get_slide_config
from report_maker.calculations.utils import to_float
from slides import add_content_slides, add_slide, draw_legend, drop_empty_placeholders, insert_charts
from utils import get_pretty_period, round_metric

logger = logging.getLogger(__name__)


def mks_pptx(task, xlsx_report_path):
    setattr(task, 'networks_table', get_networks_table(task, xlsx_report_path))

    report = ExcelDocument(xlsx_report_path)
    info = get_mks_dict_to_format(task, report)

    ppt_path = join(dirname(dirname(__file__)), basename(xlsx_report_path).replace('xlsx', 'pptx'))
    logger.info(u'%s: make %s' % (task.issue.key, basename(ppt_path)))
    ppt = Presentation(join(dirname(dirname(__file__)), 'templates', get_pptx_config(task.type_, 'pptx_template')))

    for s_num, s_value in configure_mks_slides(task, info).iteritems():
        slide_name, slide_config = s_value['slide_name'], s_value['config']

        if slide_name == 'contents':
            add_content_slides(ppt, slide_config, [u'Суммарные данные', u'Поиск', u'Сети'])

        else:
            slide = add_slide(ppt, slide_config)

            if slide_config.get('legend'):
                draw_legend(slide, slide_config['legend'], task.lang)

            if slide_config.get('charts'):
                insert_charts(report, slide, slide_config)

            if slide_config.get('tables'):
                insert_tables(slide, slide_config['tables'], **{'task': task, 'report': report})

            if slide_name not in ['title', 'conclusions', 'contacts']:
                drop_empty_placeholders(slide)

    ppt.save(ppt_path)
    return ppt_path


def configure_mks_slides(task, info):
    slides, subtitles = [], {}

    slides_yml = get_pptx_config(task.type_)
    if task.version == u'клиент+конкуренты':
        ppt_structure, version_dict = slides_yml['bench_slides'], slides_yml['bench_version']
    else:
        ppt_structure = slides_yml['client_slides']
        version_dict = slides_yml['client_version'] if task.version == u'клиент' else slides_yml['category_version']

    version_dict = get_slide_config(version_dict, info)
    for k, v in version_dict.iteritems():
        info[k] = v

    for slide_name in ppt_structure['preface']:
        if slide_name == 'method' and task.version == u'клиент':
            pass
        else:
            config = get_slide_config(slides_yml['slides'][slide_name], info)
            if slide_name == 'data':
                config['text_holders']['text_2'] = version_dict['data']
            slides.append([slide_name, config])

    for chapter_num, place in enumerate(['Total', 'Search', 'Networks'], 1):
        info['chapter_num'] = u'%02d' % chapter_num
        for k, v in slides_yml['places'][place].iteritems():
            info[k] = v

        subtitles[place] = []
        for slide_name in ppt_structure[place]:
            for template in split_template_by_titles(slides_yml['slides'][slide_name]):
                if slide_name == 'key_metrics' and task.version == u'категория':
                    pass
                else:
                    config = get_slide_config(template, info)
                    if slide_name == 'spacer':
                        config['place'] = place
                    elif slide_name != 'conclusions':
                        subtitles[place].append(config['text_holders']['title'])

                    slides.append([slide_name, config])

    for slide_name in ppt_structure['end']:
        slides.append([slide_name, get_slide_config(slides_yml['slides'][slide_name], info)])

    slides = {i: {'slide_name': slide_name, 'config': config} for i, (slide_name, config) in enumerate(slides)}

    # Формирование содержания отбивок
    # for k, v in slides.iteritems():
    #     if v['slide_name'] == 'spacer':
    #         subtitle = []
    #         [subtitle.append(x) for x in subtitles[v['config']['place']] if x not in subtitle]
    #         idx = int(ceil(len(subtitle) / 2.))
    #         v['config']['text_holders']['subtitle_1'] = subtitle[:idx]
    #         v['config']['text_holders']['subtitle_2'] = subtitle[idx:]

    return OrderedDict(sorted(slides.items()))


def get_mks_dict_to_format(task, report):

    info_ws = report['Info']
    info = {
        'name': task.created_by['name'],
        'position': task.created_by['position'],
        'lower_position': task.created_by['position'].lower(),

        'attribution': info_ws['B42'].text.lower(),
        'target': info_ws['B9'].text,
        'method_target': task.config['method_targets'].get(task.target),
        'currency': info_ws['B47'].text,
        'vat': u'с НДС' if info_ws['B52'].text == u'Да' else u'без НДС',

        'client': info_ws['B15'].text,
        'competitors': get_competitors(task),
        'category': info_ws['B20'].text,
        'region': info_ws['M4'].text,

        'analysis_period': get_pretty_period(info_ws['B31'].text, info_ws['D31'].text, info_ws['B26'].text).lower(),
        'last_month': get_pretty_period(info_ws['D31'].text, None, u'Месяцы', short=False),
        'period_1': get_pretty_period(info_ws['B36'].text, info_ws['C36'].text, info_ws['B26'].text),
        'short_period_1': get_pretty_period(info_ws['B36'].text, info_ws['C36'].text, info_ws['B26'].text, short=True),

        'period_2': get_pretty_period(info_ws['D36'].text, info_ws['E36'].text, info_ws['B26'].text),
        'short_period_2': get_pretty_period(info_ws['D36'].text, info_ws['E36'].text, info_ws['B26'].text, short=True),
    }
    for k, v in task.get_client_metrica(task.client, info['category']).iteritems():
        info[k] = v

    for metric in ['DirectClicks', task.target, 'DirectCost', 'CR', 'CPA', 'CPC']:
        value = to_float(report[task.calculations[metric]['sheet_pref']]['M5'].text)
        if metric == 'DirectCost':
            value, cap = round_metric(value, task.lang)
        else:
            cap = ''

        format_ = task.calculations[metric]['format']

        if metric == 'DirectCost':
            format_ = u'{:,.1f}' if cap else u'{:,.0f}'
            value = format_.format(value).replace(',', ' ').replace('.', ',')
            if ',' in value:
                value = value.rstrip('0').rstrip(',')
            value = u'{} {}'.format(value, cap)
        else:
            value = format_.format(value).replace(',', ' ').replace('.', ',')

        if metric == task.target:
            info['target_value'] = value
        else:
            info[metric] = value

    clicks, conversions = to_float(report[u'Клики']['M5'].text), to_float(report[u'Конверсии']['M5'].text)
    if clicks >= 0. and conversions == 0.:
        info['CPA'] = u'—'
    if clicks == 0. and conversions >= 0.:
        info['CR'] = u'—'

    return info


def get_competitors(task):
    competitors = [u'– {}'.format(client) for i, client in enumerate(task.df.Client.unique().tolist(), 1)
                   if client != task.client]
    if len(competitors) <= 8 and task.version != u'клиент':
        return u'\n'.join([u'Конкуренты:'] + competitors)

    else:
        return u''


def get_networks_table(task, xlsx_report_path):
    b_tables, t_tables = [], []

    table_cols = ['Client', 'Comp', 'Client_share', 'Comp_share']
    for param, options in task.calculations.iteritems():
        param = 'Target' if param == task.target else param
        sheet_name = u'{} (типы)'.format(options['sheet_pref'])

        b_df = pd.read_excel(
            xlsx_report_path, sheetname=sheet_name, header=None,
            skiprows=11, nrows=3, parse_cols=[12, 14, 15, 17, 18]).dropna(how='all')
        b_df.columns = ['table_name'] + ['{}_{}'.format(col, param) for col in table_cols]
        b_tables.append(b_df)

        t_df = pd.read_excel(
            xlsx_report_path, sheetname=sheet_name, header=None,
            skiprows=18, nrows=6, parse_cols=[1, 2, 3, 5, 6]).dropna(how='all')
        t_df.columns = ['table_name'] + ['{}_{}'.format(col, param) for col in table_cols]
        t_tables.append(t_df)

    b_df = pd.concat([df_.set_index(['table_name']) for df_ in b_tables], axis='columns').reset_index()
    t_df = pd.concat([df_.set_index(['table_name']) for df_ in t_tables], axis='columns').reset_index()
    df = pd.DataFrame()
    for b_row, t_rows in zip([0, 1, 2], [[0, 1], [2, 3], [4, 5]]):
        df = df.append(b_df.loc[b_row, :])
        df = df.append(t_df.loc[t_rows, :])
    df = df.reset_index(drop=True).fillna('')

    return df
