# coding: utf-8
from pptx.chart.data import ChartData
from pptx.enum.chart import (
    XL_CHART_TYPE,
    XL_DATA_LABEL_POSITION,
    XL_LEGEND_POSITION,
    XL_TICK_LABEL_POSITION,
    XL_TICK_MARK
)
from pptx.util import Pt
from . import COLORS, PPTX_GIDES, RGBColors


def create_chart_data(data):
    """
    :param data: {
        'categories': []
        'series': {
            'name': '',
            'values': []
            'color': RGBColor from pptx.dml.color
        }
    }
    :return: pptx.chart.data.ChartData object
    """
    chart_data = ChartData()
    chart_data.categories = data.get('categories', None)

    for s_num, series in enumerate(data.get('series', []), 1):
        name = series.get('name', 'Series %i' % s_num)
        values = series.get('values', [])
        chart_data.add_series(name, values)

    return chart_data


def hist(data=None, placeholder=None):
    chart_data = create_chart_data(data)
    chart = placeholder.insert_chart(XL_CHART_TYPE.COLUMN_CLUSTERED, chart_data).chart

    chart = format_legend(chart)

    chart = format_value_axis(chart, num_format='0%')
    chart = format_category_axis(chart, name=data.get('y_name'))

    chart = format_columns(chart, data, gap=150, overlap=-20)

    return chart


def stacked_bar(data=None, placeholder=None):
    chart_data = create_chart_data(data)
    chart = placeholder.insert_chart(XL_CHART_TYPE.BAR_STACKED_100, chart_data).chart

    chart = format_legend(chart)

    chart = format_value_axis(chart)
    chart = format_category_axis(chart, reverse=True)

    chart = format_columns(chart, data, gap=150, overlap=100)

    chart = add_data_labels(chart, num_format='0%')

    return chart


def nested_shows(data=None, placeholder=None):
    chart_data = create_chart_data(data)
    chart = placeholder.insert_chart(XL_CHART_TYPE.COLUMN_STACKED, chart_data).chart

    chart = format_legend(chart)

    chart = format_value_axis(chart, num_format='### ### ##0')
    chart = format_category_axis(chart, name=data['y_name'])

    chart = format_columns(chart, data)

    for i, point in enumerate(chart.series[1].points):
        text_frame = point.data_label.text_frame.paragraphs[0]

        run = text_frame.add_run()
        run.font.name, run.font.size = PPTX_GIDES['font_name'], Pt(PPTX_GIDES['font_size'])
        run.text = u'{:.0%}'.format(data['series'][1]['labels'][i])

    return chart


def nested_clicks(data=None, placeholder=None):
    chart_data = create_chart_data(data)
    chart = placeholder.insert_chart(XL_CHART_TYPE.BAR_STACKED, chart_data).chart

    chart = format_legend(chart)

    chart = format_value_axis(chart, num_format='### ### ##0')
    chart = format_category_axis(chart, tick_label_position=XL_TICK_LABEL_POSITION.NONE)

    chart = format_columns(chart, data)

    chart = add_data_labels(chart, num_format='### ### ##0')

    text_frame = chart.series[1].points[0].data_label.text_frame.paragraphs[0]
    run = text_frame.add_run()
    run.font.name, run.font.size = PPTX_GIDES['font_name'], Pt(PPTX_GIDES['font_size'])
    run.text = data['series'][1]['label']

    return chart


def line(data=None, placeholder=None):
    chart_data = create_chart_data(data)
    chart = placeholder.insert_chart(XL_CHART_TYPE.LINE, chart_data).chart

    chart.has_title, chart.has_legend = False, False

    chart = format_value_axis(chart)
    axis = chart.value_axis
    axis.minimum_scale = -0.1
    chart = format_category_axis(chart, tick_label_position=XL_TICK_LABEL_POSITION.NONE, line=False)

    chart = add_data_labels(chart, num_format='0.0%', position=XL_DATA_LABEL_POSITION.ABOVE)

    line_ = chart.series[0].format.line
    line_.color.rgb = RGBColors['yellow']
    line_.width = Pt(3)

    return chart


def cpc_hist(data=None, placeholder=None):
    chart_data = create_chart_data(data)
    chart = placeholder.insert_chart(XL_CHART_TYPE.COLUMN_CLUSTERED, chart_data).chart

    chart.has_title, chart.has_legend = False, False

    chart = format_value_axis(chart)
    chart = format_category_axis(chart, name=data.get('y_name'))
    chart.value_axis.maximum_scale = max(chart.series[0].values) * 1.4

    chart = format_columns(chart, data, gap=200, overlap=-100)

    chart = add_data_labels(chart, num_format='0.0', position=None)

    return chart


def format_legend(chart, position=XL_LEGEND_POSITION.BOTTOM):
    chart.has_legend = True

    chart.legend.font.name, chart.legend.font.size = PPTX_GIDES['font_name'], Pt(PPTX_GIDES['font_size'])

    chart.legend.position = position
    chart.legend.include_in_layout = False

    return chart


def format_value_axis(chart, num_format=None):
    axis = chart.value_axis

    axis.minimum_scale = 0
    axis.format.line.color.rgb = RGBColors['black']
    axis.format.line.color.brightness = 1
    if num_format:
        axis.has_major_gridlines = True
        axis.major_gridlines.format.line.color.rgb = RGBColors['grey']
        axis.major_gridlines.format.line.width = Pt(1)

        axis.tick_labels.font.name = PPTX_GIDES['font_name']
        axis.tick_labels.font.size = Pt(PPTX_GIDES['font_size'])

        axis.tick_labels.number_format = num_format

    else:
        axis.has_major_gridlines = False
        axis.tick_label_position = XL_TICK_LABEL_POSITION.NONE

    return chart


def format_category_axis(chart, **kwargs):
    axis = chart.category_axis

    axis.has_major_gridlines = False
    axis.format.line.color.rgb = RGBColors['black']
    if kwargs.get('line', True):
        axis.format.line.width = Pt(1)
    else:
        axis.format.line.color.brightness = 1

    axis.major_tick_mark = XL_TICK_MARK.NONE

    if kwargs.get('tick_label_position'):
        axis.tick_label_position = kwargs['tick_label_position']
    else:
        axis.tick_labels.font.name = PPTX_GIDES['font_name']
        axis.tick_labels.font.size = Pt(PPTX_GIDES['font_size'])

    if kwargs.get('name'):
        axis.has_title = True
        axis.axis_title.text_frame.text = kwargs['name']
        axis.axis_title.text_frame.paragraphs[0].font.name = PPTX_GIDES['font_name']
        axis.axis_title.text_frame.paragraphs[0].font.size = Pt(PPTX_GIDES['font_size'])
        axis.axis_title.text_frame.paragraphs[0].font.bold = False

    if kwargs.get('reverse'):
        orientation = axis._element.xpath(r'c:scaling/c:orientation')[0]
        orientation.set('val', 'maxMin')

    return chart


def format_columns(chart, data, **kwargs):
    plot = chart.plots[0]

    plot.gap_width = kwargs.get('gap', 100)
    plot.overlap = kwargs.get('overlap', 100)

    for s_num, series in enumerate(data.get('series', None)):
        fill = chart.series[s_num].format.fill
        fill.solid()

        series_color = RGBColors.get(series.get('color'))
        if not series_color:
            series_color = COLORS[s_num]
        chart.series[s_num].format.fill.fore_color.rgb = series_color

    return chart


def add_data_labels(chart, num_format=None, position=XL_DATA_LABEL_POSITION.CENTER):
    chart.plots[0].has_data_labels = True

    data_labels = chart.plots[0].data_labels
    data_labels.font.name, data_labels.font.size = PPTX_GIDES['font_name'], Pt(PPTX_GIDES['font_size'])

    data_labels.number_format = num_format

    data_labels.position = position

    return chart
