from markdown import markdown

from django.conf import settings
from django import template
from django.http import QueryDict

from console_base.utils import pretty_name as base_pretty_name

register = template.Library()


@register.filter
def startswith(value, arg):
    """Usage, {% if value|startswith:"arg" %}"""
    try:
        return value.startswith(arg)
    except AttributeError:
        return False


@register.filter
def endswith(value, arg):
    """Usage, {% if value|ends_with:"arg" %}"""
    try:
        return value.endswith(arg)
    except AttributeError:
        return False


@register.filter
def contains(value, arg):
    """Usage, {% if value|contains:"arg" %}"""
    return arg in value


@register.filter
def pretty_name(name):
    """{{ name|pretty_name }}"""
    try:
        scrub_prefixes = settings.PRETTY_NAME_SCRUB_PREFIXES
        scrub_suffixes = settings.PRETTY_NAME_SCRUB_SUFFIXES
    except AttributeError:
        scrub_prefixes = ()
        scrub_suffixes = ()

    return base_pretty_name(name=name, prefixes=scrub_prefixes, suffixes=scrub_suffixes)


@register.filter
def field_pretty_name(name):
    """{{ name|field_pretty_name }}"""
    if name.endswith('_id'):
        name = name[:-3]
    return name.replace('_', ' ').title()


@register.filter
def markdown_to_html(text):
    """
    Convert markdown text to HTML for display in templates
    """
    if text is None:
        return ''
    return markdown(text)


# Keys not of use for prefilling forms or maintaining page state.
# detail_page key should always be specifically added a URL
# and not carried over to other URLs, so include here!
JUNK_QUERY_KEYS = {'submit', 'cancel', '_method', 'detail_page'}


@register.filter
def scrub_params(qdict):
    """Remove unwanted query params for cleaner URLs"""

    params = QueryDict(mutable=True)

    for k, v in qdict.items():
        if not v or v == ['']:
            continue

        if k in JUNK_QUERY_KEYS:
            continue
        if k.startswith(('data-', 'csrf', 'cursor')):
            continue
        params[k] = v

    return params.urlencode()


@register.filter(name='smarttruncate')
def smart_truncate(value, max_length):
    """
    Truncate value to max length plus ellipsis.

    If text value is within three characters of
    max_length, then return value rather than
    truncating and adding ellipsis points.

    If word boundary within last 4 characters,
    strip off those characters as well.
    """
    full_max = max_length + 4

    if len(value) > full_max:
        truncated = value[:max_length].strip(' _-')

        # if the last portion of the string is only several characters
        # of a word, then strip off that part of the word as well
        for boundary in ' _-':
            location = truncated.rfind(boundary)
            if location == -1:
                continue

            if max_length - location < 3:
                truncated = truncated[:location]
                break

        return f'{truncated} ...'

    return value
