import logging

from django.utils.html import format_html

import django_tables2 as tables
from django_tables2.rows import BoundPinnedRow, BoundRow

logger = logging.getLogger(__name__)


# A cheat to force BoundPinnedRows to use the same rendering as BoundRows
# otherwise links don't work
# BoundPinnedRow._get_and_render_with = BoundRow._get_and_render_with


class MultiLinkColumn(tables.RelatedLinkColumn):
    """
    Like RelatedLinkColumn but allows multiple choices of accessor to be
    rendered in a hierarchy, e.g.

        accessors = ['foo.bar', 'baz.bof']
        text = '{instance.number}: {instance}'

    In this case if 'foo.bar' resolves, it will be rendered. Otherwise
    'baz.bof' will be tested to resolve, and so on. If nothing renders,
    the column will be blank. The text string will resolve using instance.
    """
    def __init__(self, accessors, **kwargs):
        """Here we force order by the accessors. By default MultiLinkColumns
        have empty_values: () to force calculation every time.
        """
        defaults = {
            'order_by': accessors,
            'empty_values': (),
        }
        defaults.update(**kwargs)
        super().__init__(**defaults)
        self.accessors = [tables.A(a) for a in accessors]

    def compose_url(self, record, bound_column):
        """Resolve the first accessor which resolves. """
        for a in self.accessors:
            try:
                return a.resolve(record).get_absolute_url()
            except (ValueError, AttributeError):
                continue
        return ""

    def text_value(self, record, value):
        """If self.text is set, it will be used as a format string for the
        instance returned by the accessor with the keyword `instance`.
        """

        for a in self.accessors:
            try:
                instance = a.resolve(record)
                if instance is None:
                    

            except ValueError:
                continue
            # Use self.text as a format string
            if self.text:
                return self.text.format(instance=instance, record=record,
                                        value=value)
            else:
                return str(instance)
        # Finally if no accessors were resolved, return value or a blank string
        # return super().text_value(record, value)
        return value or ""


class XeroLinkColumn(tables.Column):
    """Renders a badge link to the objects record in xero."""
    def render(self, value, record=None):
        if record.xero_id:
            return format_html(
                '<span class="badge progress-bar-info">'
                '<a class="alert-link" role="button" target="_blank" '
                'href="{href}">View in Xero</a></span>',
                href=record.get_xero_url()
            )


class BaseTable(tables.Table):
    class Meta:
        attrs = {"class": "table table-bordered table-striped table-hover "
                          "table-condensed"}

    # @classmethod
    # def set_header_color(cls, color):
    #     """
    #     Sets all column headers to have this background colour.
    #     """
    #     for column in cls.base_columns.values():
    #         try:
    #             column.attrs['th'].update(
    #                 {'style': f'background-color:{color};'})
    #         except KeyError:
    #             column.attrs['th'] = {'style': f'background-color:{color};'}

    def set_header_color(self, color):
        """
        Sets all column headers to have this background colour.
        """
        for column in self.columns.columns.values():
            try:
                column.column.attrs['th'].update(
                    {'style': f'background-color:{color};'})
            except KeyError:
                column.column.attrs['th'] = {
                    'style': f'background-color:{color};'}


class ModelTable(BaseTable):

    class Meta(BaseTable.Meta):
        exclude = ('id',)


class CurrencyColumn(tables.Column):
    """Render a table column as GBP."""
    def render(self, value):
        return f'£{value:,.2f}'


class NumberColumn(tables.Column):
    """Only render decimal places if necessary."""
    def render(self, value):
        if value is not None:
            return f'{value:n}'


class ColorColumn(tables.Column):
    """Render the colour in a box."""
    def __init__(self, *args, **kwargs):
        """This will ignore other attrs passed in."""
        kwargs.setdefault('attrs', {'td': {'class': "small-width text-center"}})
        super().__init__(*args, **kwargs)

    def render(self, value):
        if value:
            return format_html(
                '<div class="color-box" style="background:{};"></div>', value)

raise ValueError