from django import template
from django.utils.safestring import mark_safe
from django.core.cache import cache

from agenda_culturel.models import Category
import colorsys
from .utils_extra import *

import logging

logger = logging.getLogger(__name__)


register = template.Library()


def html_to_rgb(hex_color):
    """takes a color like #87c95f and produces a desaturate color"""
    if len(hex_color) != 7:
        raise Exception(
            "Passed %s into color_variant(), needs to be in #87c95f format." % hex_color
        )

    rgb_hex = [hex_color[x : x + 2] for x in [1, 3, 5]]
    rgb_in = [int(hex_value, 16) for hex_value in rgb_hex]

    return [x / 255 for x in rgb_in]


def rgb_to_html(rgb):
    new_rgb_int = [
        min([255, max([0, int(i * 255)])]) for i in rgb
    ]  # make sure new values are between 0 and 255

    # hex() produces "0x88", we want just "88"
    return "#" + "".join([("0" + hex(i)[2:])[-2:] for i in new_rgb_int])


def get_relative_luminance(hex_color):
    rgb = html_to_rgb(hex_color)
    R = rgb[0] / 12.92 if rgb[0] <= 0.04045 else ((rgb[0] + 0.055) / 1.055) ** 2.4
    G = rgb[1] / 12.92 if rgb[1] <= 0.04045 else ((rgb[1] + 0.055) / 1.055) ** 2.4
    B = rgb[2] / 12.92 if rgb[2] <= 0.04045 else ((rgb[2] + 0.055) / 1.055) ** 2.4

    return 0.2126 * R + 0.7152 * G + 0.0722 * B


def adjust_lightness_saturation(hex_color, shift_lightness=0.0, scale_saturation=1):
    rgb = html_to_rgb(hex_color)

    h, l, s = colorsys.rgb_to_hls(*rgb)

    l += shift_lightness
    s *= scale_saturation

    r, g, b = colorsys.hls_to_rgb(h, l, s)

    return rgb_to_html([r, g, b])


def adjust_color(color, alpha=1):
    return color + ("0" + hex(int(alpha * 255))[2:])[-2:]


def background_color_adjust_color(color, alpha=1):
    result = " background-color: " + adjust_color(color, alpha) + ";"
    if get_relative_luminance(color) < 0.5:
        result += " color: #fff;"
    else:
        result += " color: #000;"
    return result


@register.simple_tag
def css_categories():
    result = cache.get('css_categories')
    if not result: #
        result = '<style type="text/css">'

        cats = [
            {"color": c.color, "css_class": c.css_class()} for c in Category.objects.all()
        ]
        cats.append(
            {"color": Category.default_color, "css_class": Category.default_css_class}
        )

        for c in cats:
            result += "." + c["css_class"] + " {"
            result += background_color_adjust_color(
                adjust_lightness_saturation(c["color"], 0.2, 0.8), 0.8
            )
            result += "}"

            result += "." + c["css_class"] + ".circ-cat, "
            result += "form ." + c["css_class"] + ", "
            result += ".selected ." + c["css_class"] + " {"
            result += background_color_adjust_color(c["color"])
            result += "}"

            result += "." + c["css_class"] + ".circ-cat.recurrent, "
            result += ".selected.recurrent ." + c["css_class"] + " {"
            result += "background: none;"
            result += "color: " + adjust_color(c["color"]) + ";"
            result += "}"

            result += "." + c["css_class"] + ".circ-cat:hover, "
            result += "form ." + c["css_class"] + ":hover, "
            result += "a.selected:hover ." + c["css_class"] + " {"
            result += background_color_adjust_color(
                adjust_lightness_saturation(c["color"], 0.2, 1.2)
            )
            result += "}"

            result += "." + c["css_class"] + ".circ-cat.recurrent:hover, "
            result += ".selected.recurrent:hover ." + c["css_class"] + " {"
            result += "background: none;"
            result += (
                "color: "
                + adjust_color(adjust_lightness_saturation(c["color"], 0.2, 1.2))
                + ";"
            )
            result += "}"

        result += "</style>"
        cache.set('css_categories', result, 86400) # 1 day
    return mark_safe(result)


@register.filter
def small_cat(category, url=None, contrast=True, selected=True, recurrence=False):
    name = Category.default_name if category is None else category.name
    css_class = Category.default_css_class if category is None else category.css_class()

    class_contrast = " contrast" if contrast else ""
    class_selected = " selected" if selected else ""
    class_recurrence = " recurrent" if recurrence else ""

    content = (
        (
            '<span class="'
            + css_class
            + '">'
            + picto_from_name("repeat", name + " [récurrent]")
            + "</span>"
        )
        if recurrence
        else ('<span class="cat ' + css_class + '"></span>')
    )
    if url is None:
        return mark_safe(
            '<span class="small-cat'
            + class_recurrence
            + class_contrast
            + class_selected
            + '" role="button">'
            + content
            + " "
            + name
            + "</span>"
        )
    else:
        return mark_safe(
            '<a class="small-cat'
            + class_recurrence
            + class_contrast
            + class_selected
            + '" role="button" href="'
            + url
            + '">'
            + content
            + " "
            + name
            + "</a>"
        )


@register.filter
def small_cat_no_selected(category, url=None):
    return small_cat(category, url=url, selected=False)

@register.filter
def small_cat_no_contrast(category, url=None):
    if url is None:
        url = "/?category=" + str(category.pk)
    return small_cat(category, url=url, contrast=False)



@register.filter
def small_cat_recurrent(category, recurrence=False):
    return small_cat(category, url=None, selected=True, recurrence=recurrence)


@register.filter
def circle_cat(category, recurrence=False):
    if category is None:
        c = Category.default_css_class
        n = Category.default_name
    else:
        c = category.css_class()
        n = category.name

    if recurrence:
        return mark_safe(
            '<span class="cat recurrent '
            + c
            + ' circ-cat">'
            + picto_from_name("repeat", n + " [récurrent]")
            + "</span>"
        )
    else:
        return mark_safe(
            '<span class="cat ' + c + ' circ-cat" data-tooltip="' + n + '"></span>'
        )

def legend_cat(category, url, selected=True, first=False, with_title=False):
    c = category.css_class()
    n = category.name
    class_reduced = '' if selected else 'reduced'

    if category.pictogram:
        result = '<span class="cat ' + class_reduced + ' ' + c + ' circ-cat circ-large" data-tooltip="' + n + '">' + '<img src="' + category.pictogram.url + '" alt="' + category.name + '" /></span>'
    else:
        result = '<span class="cat ' + class_reduced + ' ' + c + ' circ-cat circ-large" data-tooltip="' + n + '"></span>'

    if with_title and selected:
        result = '<div class="developpe">' + result + ' <span class="titre">' + n + '</span> ' + picto_from_name('x-circle') + '</div></div>'
    else:
        result = '<div class="non-developpe">' + result + '</div>'

    result = '<a href="' + url + '">' + result + '</a>'

    return mark_safe(result)


@register.simple_tag
def show_legend(filter, category):
    cats = Category.objects.all().order_by("position")
    
    if not category is None:
        url_nocat = "/" + "/".join(filter.request.get_full_path().split("/")[2:])
        return mark_safe('<div class="button-bar">' +
            " ".join(
                [
                    legend_cat(
                        c,
                        "/cat:" + c.slug + url_nocat
                        if category != c
                        else url_nocat,
                        selected=category == c,
                        with_title=True
                    )
                    for c in cats
                ]
            )
        )
    else:
        return mark_safe("<div>" +
            " ".join(
                [legend_cat(c, "/cat:" + c.slug + filter.request.get_full_path()) for c in cats]
            ) + "</div>"
        )
