# coding: utf-8
"""general colors"""
import collections

FONT_NAME = u'Arial'
TITLE_FONT_NAME = u'Arial (Заголовки)'
FONT_SIZE = 18
TITLE_FONT_SIZE = 24

# Менять порядок цветов нельзя - это палитра дизайнеров
COLORS = [
    '#ff3333',  # red
    '#ffcc00',  # yellow
    '#0077ff',  # blue
    '#23b324',  # green
    '#5dcef9',  # sky blue
    '#6838cf',  # violet
    '#c62cd0',  # magenta
    '#ff9a00',  # orange

    # pale
    '#ff8585',  # red
    '#ffe066',  # yellow
    '#66adff',  # blue
    '#6ae26b',  # green
    '#9ee2fb',  # sky blue
    '#a488e2',  # violet
    '#de7fe4',  # magenta
    '#ffc266',  # orange

    '#bfbfbf',  # grey
    '#a6a6a6',  # dark grey
    '#d9d9d9'   # light grey
]


def Chart(workbook, type_, subtype, title):
    # Create chart
    chart = workbook.add_chart({'type': type_, 'subtype': subtype})

    chart.set_size({'width': 900, 'height': 600})
    chart.set_chartarea({
        'border': {'none': True},
        'fill': {'none': True}
    })
    chart.set_plotarea({
        'border': {'none': True},
        'fill': {'none': True}
    })

    chart.set_title({
        'name': title,
        'name_font': {
            'size': TITLE_FONT_SIZE,
            'name': TITLE_FONT_NAME,
            'bold': True
        }
    })

    chart.set_x_axis({
        'num_font': {
            'size': FONT_SIZE,
            'name': FONT_NAME,
            'bold': False
        },
        'line': {'none': True},
        'major_tick_mark': 'none',
        'minor_tick_mark': 'none',
        'major_gridlines': {'visible': False}
    })

    chart.set_y_axis({
        'reverse': True,
        'crossing': 'max',
        'num_font': {
            'size': FONT_SIZE,
            'name': FONT_NAME,
            'bold': False
        },
        'name_font': {
            'size': FONT_SIZE,
            'name': FONT_NAME,
            'bold': False
        },
        'line': {
            'visible': True,
            'width': 1,
            'color': '#000000'
        },
        'major_tick_mark': 'none',
        'minor_tick_mark': 'none'
    })

    chart.set_legend({
        'position': 'bottom',
        'font': {
            'size': FONT_SIZE,
            'name': FONT_NAME,
            'bold': False
        }
    })

    return chart


def chart_add_series(chart, num, opt):
    def_fmt = {
        'data_labels': {
            'value': True,
            'num_format': '### ### ### ### ##0',
            'font': {
                'size': FONT_SIZE,
                'name': FONT_NAME,
                'bold': False
            }
        },
        'fill': {'color': COLORS[num]},
        'line': {'color': COLORS[num]},
        'marker': {
            'type': 'diamond',
            'size': 9,
            'fill': {'color': COLORS[num]},
            'border': {'color': COLORS[num]}
        }
    }

    # fixme(n-bar) добавить обновление для опций произволной глубины
    if opt:
        for k in opt:
            if isinstance(opt[k], dict):
                def_fmt[k].update(opt[k])
            else:
                def_fmt[k] = opt[k]

    chart.add_series(def_fmt)


def colorize_table_rows(writer, sheet_name, first_row_idx, first_col_idx, last_row_idx, last_col_idx, **kwargs):
    if kwargs.get('values'):
        min_value, mid_value, max_value = kwargs['values']
    else:
        min_value, mid_value, max_value = 0, 100, 150

    if kwargs.get('colors'):
        min_color, mid_color, max_color = kwargs['colors']
    else:
        min_color, mid_color, max_color = COLORS[0], COLORS[3], COLORS[10]

    wb = writer.book
    format = wb.add_format(kwargs.get('format', None))
    sheet = wb.get_worksheet_by_name(sheet_name)
    CELL_HEIGHT, CELL_WIDTH = 27, 4

    COLORIZE_OPT = {
        'type': '3_color_scale',
        'min_type': 'num',
        'min_value': min_value,
        'min_color': min_color,  # red
        'mid_type': 'num',
        'mid_value': mid_value,
        'mid_color': mid_color,  # green
        'max_type': 'num',
        'max_value': max_value,
        'max_color': max_color  # magenta
    }
    sheet.set_column(first_col_idx, last_col_idx, None, format)

    for row_idx in range(first_row_idx, last_row_idx + 1):
        if kwargs.get('set_cell_size', True):
            sheet.set_row(row_idx, CELL_HEIGHT)
        sheet.conditional_format(row_idx, first_col_idx, row_idx, last_col_idx, COLORIZE_OPT)

    if kwargs.get('set_cell_size', True):
        sheet.set_column(first_col_idx, last_col_idx, CELL_WIDTH, format)

    return writer


def GidesChart(workbook, **gides):

    chart = workbook.add_chart({'type': gides.get('type'),
                                'subtype': gides.get('subtype')
                                })

    chart.set_size(gides.get('size'))
    chart.set_chartarea(gides.get('areas'))
    chart.set_plotarea(gides.get('areas'))

    if gides.get('title').get('name'):
        chart.set_title(gides.get('title'))

    chart.set_legend(gides.get('legend'))

    chart.set_x_axis(gides.get('x_axis'))
    chart.set_y_axis(gides.get('y_axis'))
    if gides.get('y2_axis'):
        chart.set_y2_axis(gides.get('y2_axis'))

    return chart


def update_chart_config(custom_config, chart_config):
    for k, v in chart_config.iteritems():
        if isinstance(v, collections.Mapping):
            custom_config[k] = update_chart_config(custom_config.get(k, {}), v)
        else:
            custom_config[k] = v
    return custom_config


def customize_chart_config(base_config, chart_config):
    custom_config = update_chart_config(base_config, chart_config)
    return custom_config


def add_series_by_rows(sheet_name, chart, custom_config):

    for snum, row in enumerate(range(custom_config.get('first_row'), custom_config.get('last_row'))):

        series_config = custom_config.get('ranges').copy()
        for k, v in series_config.iteritems():
            series_config[k] = u'=\'{sheet_name}\'!{range}'.format(sheet_name=sheet_name, range=v.format(row=row))
        try:
            series_config['fill'] = {'color': custom_config.get('colors')[snum]}
        except IndexError:
            series_config['fill'] = {'color': custom_config.get('colors')[len(custom_config.get('colors')) - 1]}

        if custom_config.get('add_series_options'):
            add_series_options = None
            if custom_config['add_series_options'].get(snum):
                add_series_options = custom_config['add_series_options'][snum]
            elif custom_config['add_series_options'].get('common'):
                add_series_options = custom_config['add_series_options']['common']

            if add_series_options is not None:
                series_config = customize_chart_config(series_config, add_series_options)

        chart.add_series(
            dict(series_config.items() + custom_config.get('column_series_options').items())
        )

    return chart


def add_series_by_columns(sheet_name, chart, custom_config):

    for snum, col in enumerate(custom_config.get('columns')):
        series_config = custom_config.get('ranges').copy()
        for k, v in series_config.iteritems():
            series_config[k] = u"='{sheet_name}'!{range}".format(
                sheet_name=sheet_name, range=v.format(column=col, row=custom_config.get('last_row')))
        series_config['fill'] = {'color': custom_config.get('colors')[snum]}

        if custom_config.get('add_series_options'):
            if custom_config.get('add_series_options').get(snum):
                add_series_options = custom_config.get('add_series_options').get(snum)
                if add_series_options.get("categories"):
                    add_series_options["categories"] = u"='{sheet_name}'!{range}".format(
                        sheet_name=sheet_name, range=add_series_options.get("categories"))
                series_config = customize_chart_config(series_config, add_series_options)

        chart.add_series(
            dict(series_config.items() + custom_config.get('column_series_options').items())
        )

    return chart
