# coding: utf-8
from pptx.enum.shapes import MSO_SHAPE_TYPE
from pptx.enum.text import PP_ALIGN
from pptx.util import Pt

from . import PPTX_GIDES
from .pptx_charts import cpc_hist, hist, line, nested_clicks, nested_shows, stacked_bar
from .time_targeting_table import add_table


def add_slide(pptx, sl_yml):
    layout = get_layout_by_name(pptx, sl_yml['layout'])
    slide = pptx.slides.add_slide(layout)
    slide = fill_text_holders(slide, sl_yml.get('text_holders', {}))

    if sl_yml['layout'] == 'table':
        slide = add_table(slide, sl_yml['table_data'])

    if sl_yml.get('charts'):
        for ch_yml in sl_yml['charts']:
            placeholder = get_placeholder_by_name(slide, ch_yml.get('placeholder', 'chart_1'))
            get_chart_fn(ch_yml['chart_type'])(ch_yml['data'], placeholder)

    if sl_yml['layout'] in ['Contents', 'Spacer']:
        slide = drop_empty_placeholders(slide)

    if sl_yml.get('hidden', False):
        element = slide._element
        element.set('show', '0')

    return slide


def get_chart_fn(chart_type):
    if chart_type == 'hist':
        return hist
    if chart_type == 'stacked_bar':
        return stacked_bar
    elif chart_type == 'nested_shows':
        return nested_shows
    elif chart_type == 'nested_clicks':
        return nested_clicks
    elif chart_type == 'line':
        return line
    elif chart_type == 'cpc_hist':
        return cpc_hist


def drop_empty_placeholders(slide):
    for shape in slide.shapes:
        if shape.shape_type is not MSO_SHAPE_TYPE.AUTO_SHAPE and shape.shape_type is not MSO_SHAPE_TYPE.PICTURE:
            if shape.has_text_frame:
                if not shape.text_frame.text:
                    shape.element.getparent().remove(shape.element)

            elif not shape.has_chart and not shape.has_table:
                shape.element.getparent().remove(shape.element)

    return slide


def fill_text_holders(slide, sl_yml):
    for ph_name, content in sl_yml.iteritems():
        if type(content) == list:
            try:
                for p_num, text in enumerate(content, 1):
                    text_holder = get_placeholder_by_name(
                        slide, '{}_{}'.format(ph_name, p_num))
                    text_holder.text_frame.text = text
            except:
                write_bullet_list(slide, ph_name, content)

        else:
            text_holder = get_placeholder_by_name(slide, ph_name)
            text_holder.text_frame.text = content

    return slide


def write_bullet_list(slide, ph_name, texts):
    text_holder = get_placeholder_by_name(slide, ph_name)

    text_frame = text_holder.text_frame
    for p_num, text in enumerate(texts):
        paragraph = text_frame.paragraphs[0] if p_num == 0 else text_frame.add_paragraph()

        paragraph.font.name = PPTX_GIDES['font_name']
        if 'subtitle' in ph_name:
            paragraph.font.size = Pt(32)
        else:
            paragraph.font.size = Pt(PPTX_GIDES['font_size'])

        paragraph.text = text
        paragraph.alignment = PP_ALIGN.LEFT
        paragraph.level = 2

    return slide


def get_layout_by_name(pptx, lo_name):
    for layout in pptx.slide_layouts:
        if layout.name == lo_name:
            return layout
    return None


def get_placeholder_by_name(slide, ph_name):
    layout = slide.slide_layout
    for placeholder in layout.placeholders:
        if placeholder.name == ph_name:
            if ph_name == 'slide_number':
                return placeholder
            else:
                ph_idx = placeholder.placeholder_format.idx
                return slide.placeholders[ph_idx]
    return None
