# -*- coding: utf-8 -*-
import unicodedata

import re
import six
from django.contrib.sites.shortcuts import get_current_site
from django.db.models import ManyToManyField
from django.forms import MultipleChoiceField, ModelMultipleChoiceField
from django.utils.encoding import force_text
from django.utils.functional import allow_lazy
from django.utils.safestring import mark_safe, SafeText
from django.utils.text import slugify


def query_dict_to_dict(query_dict, list_list=[], form=None, fields=None):
    multiple_field_classes = [MultipleChoiceField, ModelMultipleChoiceField, ManyToManyField]
    return_dict = {}
    if fields:
        fields_list = [field.name for field in fields]
    for key, list_obj in query_dict.iterlists():
        if (form and key not in form.fields) or (fields and key not in fields_list):
            continue
        if len(list_obj) > 1 or key in list_list or (form and form.fields[key].__class__ in multiple_field_classes) or \
                (fields and fields[fields_list.index(key)].__class__ in multiple_field_classes):
            return_dict[key] = list_obj
        else:
            return_dict[key] = list_obj[0]
    return return_dict


def get_first(iterable, default=None):
    if iterable:
        for item in iterable:
            return item
    return default


def safe_unicode(tstr):
    if type(tstr) is str:
        try:
            try:
                return tstr.decode('utf-8')
            except UnicodeDecodeError:
                return tstr.decode('windows-1250')
        except UnicodeDecodeError:
            return tstr.decode()
    return tstr


def percentage(part, whole, round_to=None):
    if whole and part:
        try:
            value = 100 * float(part) / float(whole)
            if round_to:
                return round(value, round_to)
            else:
                return value
        except TypeError:
            return u'Błąd'
    else:
        return 0


_NUMERALS = '0123456789abcdefABCDEF'
_HEXDEC = {v: int(v, 16) for v in (x + y for x in _NUMERALS for y in _NUMERALS)}
LOWERCASE, UPPERCASE = 'x', 'X'


def parse_rgb_hex(hex_rgb):
    if hex_rgb[0] == '#':
        hex_rgb = hex_rgb[1:]
    return _HEXDEC[hex_rgb[0:2]], _HEXDEC[hex_rgb[2:4]], _HEXDEC[hex_rgb[4:6]]


def parse_rgb_hex_str(hex_rgb, alpha=None):
    triplet = parse_rgb_hex(hex_rgb)
    rgb_str = '{}, {}, {}'.format(*triplet)
    if alpha:
        rgb_str += ', {}'.format(alpha)
    return rgb_str


def custom_slugify(value, allow_unicode=False):
    """
    Convert to ASCII if 'allow_unicode' is False. Convert spaces to hyphens.
    Remove characters that aren't alphanumerics, underscores, or hyphens.
    Convert to lowercase. Also strip leading and trailing whitespace.
    """
    value = force_text(value)
    if allow_unicode:
        value = unicodedata.normalize('NFKC', value)
        value = re.sub('[^\w\s-]', '', value, flags=re.U).strip().lower()
        return mark_safe(re.sub('[-\s]+', '-', value, flags=re.U))
    else:
        value = re.sub(u'ł', 'l', value).strip().lower()
    value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii')
    value = re.sub('[^\w\s-]', '', value).strip().lower()
    return mark_safe(re.sub('[-\s]+', '-', value))


custom_slugify = allow_lazy(custom_slugify, six.text_type, SafeText)


def underscore_to_camelcase(value):
    def camelcase():
        yield str.lower
        while True:
            yield str.capitalize

    c = camelcase()
    return ''.join(c.next()(x) if x else '_' for x in value.split('_'))


def jsify_variables(value):
    if type(value) is not dict:
        return value
    output_dict = {}
    for underscore_field, internal_value in value.iteritems():
        camelcase_field = underscore_to_camelcase(underscore_field)
        output_dict[camelcase_field] = jsify_variables(internal_value)
    return output_dict


def normalize_polish_chars(text):
    trans_tab = {u'ą': 'a', u'ć': 'c', u'ę': 'e', u'ł': 'l', u'ń': 'n', u'ó': 'o', u'ś': 's', u'ż': 'z', u'ź': 'z',
                 u'Ą': 'A', u'Ć': 'C', u'Ę': 'E', u'Ł': 'L', u'Ń': 'N', u'Ó': 'O', u'Ś': 'S', u'Ż': 'Z', u'Ź': 'Z'}
    return ''.join(trans_tab.get(char, char) for char in text)


def safe_ascii(text):
    text = normalize_polish_chars(text)
    text_safe = ""
    for char in text:
        if not ord(char) < 48 or ord(char) > 127:
            text_safe += char
    return slugify(text_safe)


def progress_percent(value, all):
    try:
        return int(float(int(value)) / (float(int(all))) * 100)
    except ValueError:
        return -1
    except ZeroDivisionError:
        return 0


def get_base_url_from_request(request):
    current_site = get_current_site(request)
    domain = current_site.domain
    return domain
