# -*- coding: utf-8 -*-
from lxml import html

from django.utils.html import conditional_escape
from django.utils.encoding import force_str


class AsDictWidget(object):
    def __init__(self, form, field_name, field):
        self.form = form
        self.field_name = field_name
        self.field = field
        self.bound_field = self.form[self.field_name]

    def as_dict(self):
        return {
            'errors': [conditional_escape(i) for i in self.bound_field.errors],
            'help_text': self.field.help_text,
            'widget': self.field.widget.__class__.__name__,
            'label': force_str(self.bound_field.label),
            'label_image': self.field.label_image,
            'is_required': self.field.required,
            'tags': self.parse_tags(),
            'other_data': self.get_other_data(),
            'error_messages': self.field.error_messages,
            'is_hidden': self.field.widget.is_hidden,
            'page': self.field.page,
            'position': self.field.position,
            'group_slug': self.field.group_slug,
            'hints': getattr(self.field, 'hints', [])
        }

    def parse_tags(self):
        return self.parse_tags_from_html(force_str(self.bound_field))

    def parse_tags_from_html(self, html_text):
        html_object = html.fromstring(html_text)
        tags = []

        for element in html_object.cssselect('input,textarea,select'):
            tag_name = element.tag
            attrs = dict(element.attrib) or {}
            if tag_name == 'input':
                tag = self.get_tag_for_input(element, attrs, html_object)
            elif tag_name == 'textarea':
                tag = self.get_tag_for_textarea(element, attrs)
            elif tag_name == 'select':
                tag = self.get_tag_for_select(element, attrs)
            tags.append(tag)
        return tags

    def get_tag_for_input(self, element, attrs, full_html_object):
        tag = {
            'tag': 'input',
            'attrs': attrs
        }
        if tag['attrs']['type'] in ['checkbox', 'radio']:
            label_text = None
            if attrs.get('id'):
                labels_list = full_html_object.cssselect('label[for=%s]' % attrs.get('id'))
                if labels_list:
                    label_text = labels_list[0].text_content()

            if not label_text:
                label_text = ''
            tag['label'] = label_text.strip()
        if 'value' in tag['attrs']:
            tag['attrs']['value'] = tag['attrs']['value']
        return tag

    def get_tag_for_textarea(self, element, attrs):
        return {
            'tag': 'textarea',
            'attrs': attrs,
            'content': element.text
        }

    def get_tag_for_select(self, element, attrs):
        tag = {
            'tag': 'select',
            'attrs': attrs
        }
        options = []
        for option in element.cssselect('option'):
            options.append({
                'attrs': dict(option.attrib) or {},
                'content': option.text,
            })
        tag['options'] = options
        return tag

    def get_other_data(self):
        return getattr(self.field, 'other_data', {})


class DataSourceFieldWidget(object):
    def __init__(self, form, field_name, field):
        self.form = form
        self.field_name = field_name
        self.field = field
        self.bound_field = self.form[self.field_name]
        self.group_position_counter = None
        if getattr(self.field, 'group_id', None):
            self.group_position_counter = field_name.split('__')[-1]

    def as_dict(self):
        # todo: me
        return {
            'type': 'choices',
            'errors': [conditional_escape(i) for i in self.bound_field.errors],
            'help_text': self.field.help_text,
            'label': force_str(self.bound_field.label),
            'label_image': self.field.label_image,
            'is_required': self.field.required,
            'error_messages': self.field.error_messages,
            'show_conditions': getattr(self.field, 'other_data', {}).get('show_conditions'),
            'data_source': self.field.question.get_data_source_data(
                user=self.form.instance,
                questions_dict=self.field.questions_dict,
                group_position_counter=self.group_position_counter,
            ),
            'is_allow_multiple_choice': self.field.question.param_is_allow_multiple_choice,
            'widget': self.field.question.param_widget,
            'value': self.bound_field.value(),
            'is_hidden': self.field.question.param_is_hidden,
            'is_disabled_init_item': self.field.question.param_is_disabled_init_item,
            'suggest_choices': self.field.question.param_suggest_choices,
            'group_slug': self.field.group_slug,
            'page': self.field.page,
            'position': self.field.position,
        }
