# -*- coding: utf-8 -*-
import logging
from pptx.enum.text import MSO_ANCHOR, PP_ALIGN
from pptx.oxml.xmlchemy import OxmlElement
from pptx.util import Cm, Pt
from presentation import GIDES, RGBColors, TAB_PARAMS
from check_rules import get_fill_color, get_fill_rules

logger = logging.getLogger(__name__)


def add_table(slide, df, **kwargs):
    if df.empty:
        logger.warning('empty table')
        return slide

    rows, cols = df.shape[0] + 1, df.shape[1]

    top, left = kwargs.get('top', TAB_PARAMS['top']), kwargs.get('left', TAB_PARAMS['left'])
    height, width = kwargs.get('height', TAB_PARAMS['tab_height']), kwargs.get('width', TAB_PARAMS['tab_width'])

    row_height, col_width = get_cell_params(
        rows, cols, width, height,
        kwargs.get('min_row_height', TAB_PARAMS['cell_height']),
        kwargs.get('min_col_width', TAB_PARAMS['cell_width']),

        kwargs.get('max_row_height', TAB_PARAMS['max_row_height']),
        kwargs.get('max_col_width', TAB_PARAMS['max_col_width'])
    )

    table = slide.shapes.add_table(
        rows, cols, Cm(left), Cm(top), Cm(width), Cm(height)
    ).table

    table = fill_table_header(table, df.columns, col_width)

    for r_idx, row in enumerate(df.itertuples(), 1):
        table.rows[r_idx].height = Cm(row_height)

        data_name = row[0]
        for c_idx, value in enumerate(row[1:]):
            cell = table.cell(r_idx, c_idx)

            if c_idx == 0:
                cell.text = unicode(value)
                format_cell(
                    cell,
                    alignment=PP_ALIGN.LEFT,
                    # border_color=RGBColors['pale_grey']
                )

            else:
                fill_color, cell_text = get_fill_color(
                    get_fill_rules(data_name, value), value
                )

                cell.text = yes_or_no(cell_text, kwargs.get('lang'))
                format_cell(
                    cell,
                    alignment=PP_ALIGN.RIGHT,
                    fill_color=fill_color
                )

    return slide


def yes_or_no(value, lang):
    if lang == 'ru':
        return value
    else:
        if value == u'да':
            return 'yes'
        elif value == u'нет':
            return 'no'
        else:
            return value


def get_min_height(df1, df2):
    if df1.empty or df2.empty:
        return TAB_PARAMS['cell_height']

    rows1, rows2 = df1.shape[0] + 1, df2.shape[0] + 1
    height1 = min((TAB_PARAMS['tab_height'] - TAB_PARAMS['header_height']) / (rows1 - 1), TAB_PARAMS['cell_height'])
    height2 = min((TAB_PARAMS['tab_height'] - TAB_PARAMS['header_height']) / (rows2 - 1), TAB_PARAMS['cell_height'])

    return min(height1, height2)


def get_cell_params(rows, cols, width, height,
                    min_height, min_width, max_height, max_width):

    row_height = max(min((height - TAB_PARAMS['header_height']) / (rows - 1), min_height), min_height)
    col_width = max(min((width - TAB_PARAMS['first_col_width']) / (cols - 1), max_width), min_width)

    return row_height, col_width


def fill_table_header(table, header, col_width):
    table.rows[0].height = Cm(TAB_PARAMS['header_height'])
    for col_num, column in enumerate(table.columns):
        cell = table.cell(0, col_num)

        if col_num == 0:
            column.width = Cm(TAB_PARAMS['first_col_width'])

        else:
            cell.text = header[col_num][:25]
            column.width = Cm(col_width)

        format_cell(
            cell,
            font_name=GIDES['font_name'],
            border_width=Pt(TAB_PARAMS['header_border_width'])
        )

    return table


def format_cell(cell, **kwargs):
    remove_borders(cell, ['right'])
    set_cell_border(
        cell,
        'bottom',
        kwargs.get('border_color', RGBColors['black']),
        kwargs.get('border_width', Pt(TAB_PARAMS['cell_border_width']))
    )
    cell.margin_top = Cm(0)
    cell.margin_bottom = Cm(0)

    cell.margin_left = Cm(TAB_PARAMS['margin'])
    cell.margin_right = Cm(TAB_PARAMS['margin'])

    cell.vertical_anchor = MSO_ANCHOR.MIDDLE

    cell.fill.solid()
    cell.fill.fore_color.rgb = kwargs.get('fill_color', RGBColors['white'])

    paragraph = cell.text_frame.paragraphs[0]
    paragraph.alignment = kwargs.get('alignment', PP_ALIGN.CENTER)

    paragraph.font.color.rgb = RGBColors['black']
    paragraph.font.size = GIDES['font_size']
    paragraph.font.name = kwargs.get('font_name', GIDES['font_name'])
    paragraph.font.bold = False

    return cell


def SubElement(parent, tag_name, **kwargs):
    element = OxmlElement(tag_name)
    element.attrib.update(kwargs)
    parent.append(element)
    return element


def set_cell_border(cell, border_type, border_color=RGBColors['black'], border_width=Pt(1)):
    lines = {
        'top': 'a:lnT',
        'bottom': 'a:lnB',
        'left': 'a:lnL',
        'right': 'a:lnR'
    }

    tc = cell._tc
    tcPr = tc.get_or_add_tcPr()

    border = SubElement(tcPr, lines[border_type], w=str(border_width), cap='flat', cmpd='sng', algn='ctr')
    solidFill = SubElement(border, 'a:solidFill')
    SubElement(solidFill, 'a:srgbClr', val=str(border_color))
    SubElement(border, 'a:prstDash', val='solid')
    SubElement(border, 'a:round')
    SubElement(border, 'a:headEnd', type='none', w='med', len='med')
    SubElement(border, 'a:tailEnd', type='none', w='med', len='med')

    return border


def remove_borders(cell, border_types=('top', 'bottom', 'left', 'right')):
    lines = {
        'top': 'a:lnT',
        'bottom': 'a:lnB',
        'left': 'a:lnL',
        'right': 'a:lnR'
    }

    for line in [lines[border_type] for border_type in border_types]:
        tc = cell._tc
        tcPr = tc.get_or_add_tcPr()

        border = SubElement(tcPr, line, w=str(12700), cap='flat', cmpd='sng', algn='ctr')
        SubElement(border, 'a:noFill')

    return cell
