# -*- coding: utf-8 -*-
import logging
from lxml.etree import SubElement
from exceller.cell import Cell
from cpa_task.make_requests import get_region_names
from cpa_task.utils import convert_name
from templates import read_yml_config

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


def fill_info_ws(ws, task, info, region):
    for address, cell in info.iteritems():
        ws[address].text = cell

    ids = u''.join([let for let in str(region['region_ids'].encode('utf-8')) if let.isdigit() or let in [',']])
    ids = [int(id.strip()) for id in ids.split(',') if id.strip()]
    if ids:
        for row_num, id in enumerate(ids):
            pretty_region = get_region_names(id, task.lang)
            ws.set_cell_value(5 + row_num, 13, id)
            ws.set_cell_value(5 + row_num, 14, pretty_region)

    if task.type_ == 'retail':
        for col_num, col_name in zip([16, 17, 18], ['Place', 'Device', 'Client']):
            filters = task.data_filters.get(col_name, [])
            if not filters:
                filters = task.df[col_name].unique().tolist()

            if col_name == 'Client':
                filters = [competitor for competitor in filters if competitor != task.client]

            for row_num, filter_ in enumerate(filters):
                if DICTS.get(col_name):
                    ws.set_cell_value(5 + row_num, col_num, convert_name(filter_, DICTS[col_name], to_local=False))
                else:
                    ws.set_cell_value(5 + row_num, col_num, filter_)

    return ws


def write_df(ws, df):
    if hasattr(df, 'descr'):
        descr = df.descr

        if descr.get('target_range'):
            ws.clear_contents(descr['target_range'])

        if descr.get('columns'):
            df = df.loc[:, descr['columns']]

        start_row, start_col = descr['position']['row'], descr['position']['column']
        if descr.get('draw_column_names', False):
            for col, col_name in enumerate(df.columns, 1):
                ws.set_cell_value(start_row, start_col + col - 1, col_name)
            start_row += 1

    else:
        start_row, start_col = 1, 1

    for col, col_name in enumerate(df.columns, 1):
        for row in range(df.shape[0]):
            ws.set_cell_value(start_row + row, start_col + col - 1, df[col_name][row])

    return ws


def format_charts(report, charts_config):
    for charts in charts_config:
        ws = report[charts['ws_name']]
        axe_max = 0
        for rng_cells in charts['range']:
            cells = [cell.strip() for cell in rng_cells.split(',')]
            for cell in ws.range(cells[0], cells[1]):
                axe_max = max(axe_max, float(cell.text))
        axe_max = axe_max * 1.4

        for chart_name in charts['charts']:
            try:
                chart = ws.charts[chart_name]

                axis_max = chart.root.find('c:chart/c:plotArea/c:valAx/c:scaling/c:max',
                                           namespaces=chart.chart_element.nsmap)
                if axis_max is None:
                    scaling = chart.root.find('c:chart/c:plotArea/c:valAx/c:scaling',
                                              namespaces=chart.chart_element.nsmap)
                    axis_max = SubElement(scaling, '{%s}max' % scaling.nsmap['c'])

                axis_max.set('val', str(axe_max))

            except KeyError:
                pass

    return report


def rng_formula_to_address(ws, ranges, columns, first_row):
    for column, rng_name in zip(columns, ranges):
        addr = get_range_addr(ws, first_row, column)
        ws.doc.set_named_range(rng_name, addr)

    return ws


def get_range_addr(ws, cell_row, cell_column, horizontal=False):
    first_cell = ws.rows[cell_row].get_cell(cell_column)

    if horizontal:
        last_cell = get_last_cell_hor(ws, cell_row, cell_column)
    else:
        last_cell = get_last_cell_ver(ws, cell_row, cell_column)

    addr = u'\'{ws_name}\'!${first_col}${first_row}:${last_col}${last_row}'.format(
        ws_name=ws.name.decode('utf-8') if type(ws.name) != unicode else ws.name,
        first_col=Cell.column_to_letter(first_cell.col_index),
        first_row=first_cell.row.row_index,
        last_col=Cell.column_to_letter(last_cell.col_index),
        last_row=last_cell.row.row_index
    )

    return addr


def get_last_cell_hor(ws, cell_row, cell_column):
    column = cell_column
    first_cell = ws.rows[cell_row].get_cell(column)
    last_cell = None
    while ws.rows[cell_row].get_cell(column):
        if ws.rows[cell_row].get_cell(column).text:
            last_cell = ws.rows[cell_row].get_cell(column)
            column += 1
        else:
            break

    if last_cell is None:
        last_cell = first_cell

    return last_cell


def get_last_cell_ver(ws, cell_row, cell_column):
    row = cell_row
    first_cell = ws.rows[row].get_cell(cell_column)
    last_cell = None
    while ws.rows.get(row):
        if ws.rows[row].get_cell(cell_column).text:
            last_cell = ws.rows[row].get_cell(cell_column)
            row += 1
        else:
            break

    if last_cell is None:
        last_cell = first_cell

    return last_cell
