# coding=utf-8
from django import forms
from django.forms import ChoiceField, CharField
from django.contrib.admin.widgets import AdminTextInputWidget
from django.forms import ValidationError
from dal import autocomplete

from libs.autocomplete import BaseAutocompleteListView, LongListSelectWidget
from ..models.interpose import Interpose
from ..utils.rpc_data import (
    search_tags_by_name, get_services_by_ids, get_doctors_by_ids,get_diary_by_ids,
    get_tags_by_ids, search_doctors_by_id_prefix)
from gm_types.gaia import TAG_TYPE, DOCTOR_TYPE
from gm_types.doris import INTERPOSE_TYPE


def tag_option(tag):
    assert 'id' in tag and 'name' in tag
    if tag['tag_type'] == TAG_TYPE.PROVINCE:
        tag['name'] += '(省)'
    return tag['id'], '%d: %s' % (tag['id'], tag['name'])


def service_option(service):
    assert 'id' in service and 'name' in service
    label = '%d: %s' % (service['id'], service['name'],)
    if 'doctor' in service:
        label += ' - %s' % service['doctor']['name']
        if 'hospital' in service['doctor']:
            label += '@%s' % service['doctor']['hospital']['name']
    return str(service['id']), label


def doctor_option(doctor):
    assert 'did' in doctor and 'name' in doctor and 'hospital' in doctor
    label = '%s: %s' % (doctor['did'], doctor['name'],)
    if doctor['hospital']:
        label += '@%s' % doctor['hospital']
    return doctor['did'], label

def diary_option(diary):
    # assert 'id' in diary and 'title' in diary
    label = '%d: %s' % (diary['id'], diary['data']['title'],)
    return str(diary['id']), label

class CityTagIDAutocompleteView(BaseAutocompleteListView):
    def get_list_by_query(self, q):
        if q == '':
            return [(0, '全部')]
        else:
            tags = search_tags_by_name(query=q, tag_types=[TAG_TYPE.CITY, TAG_TYPE.PROVINCE])
            res = []
            for tag in tags:
                res.append(tag_option(tag))

            return res


class ItemTagIDAutocompleteView(BaseAutocompleteListView):
    def get_list_by_query(self, q):
        if q == '':
            return [(0, '全部')]
        else:
            tags = search_tags_by_name(query=q, tag_types=[
                TAG_TYPE.BODY_PART,
                TAG_TYPE.BODY_PART_SUB_ITEM,
                TAG_TYPE.ITEM_WIKI,])
            res = []
            for tag in tags:
                res.append(tag_option(tag))

            return res


class ObjectIDAutocompleteView(BaseAutocompleteListView):
    def get_list_by_query(self, q):
        if not self.q:
            return []

        assert self.forwarded and 'interpose' in self.forwarded
        interpose_id = int(self.forwarded['interpose'])
        interpose = Interpose.objects.get(pk=interpose_id)
        interpose_type = interpose.interpose_type

        if interpose_type in (
            INTERPOSE_TYPE.SERVICE_FILTER,
            INTERPOSE_TYPE.SERVICE_SEARCH,
        ):
            services = get_services_by_ids(ids=[int(q), ])
            res = []
            for service in services:
                res.append(service_option(service))
            return res
        elif interpose_type in (
            INTERPOSE_TYPE.DIARY_SEARCH,
            INTERPOSE_TYPE.DIARY_FILTER,
        ):
            diaries = get_diary_by_ids(ids=[int(q), ])
            res = []
            for diary in diaries:
                res.append(diary_option(diary))
            return res
        elif interpose_type in (
            INTERPOSE_TYPE.DOCTOR_SEARCH,
            INTERPOSE_TYPE.DOCTOR_FILTER,
            INTERPOSE_TYPE.OFFICER_SEARCH,
            INTERPOSE_TYPE.OFFICER_FILTER,
        ):
            if interpose_type in [INTERPOSE_TYPE.DOCTOR_SEARCH, INTERPOSE_TYPE.DOCTOR_FILTER]:
                doctor_type = DOCTOR_TYPE.DOCTOR
            else:
                doctor_type = DOCTOR_TYPE.OFFICER
            doctors = search_doctors_by_id_prefix(id_prefix=q, doctor_type=doctor_type)
            res = []
            for doctor in doctors:
                res.append(doctor_option(doctor))
            return res
        else:
            raise NotImplementedError


class InterposeTypeAutocompleteView(BaseAutocompleteListView):
    def get_list_by_query(self, q):
        return [t for t in INTERPOSE_TYPE]


class SortOrderAutocompleteView(BaseAutocompleteListView):
    def get_list_by_query(self, q):
        if all((
            self.forwarded,
            'interpose_type' in self.forwarded,
            self.forwarded['interpose_type'] in Interpose.SORT_ORDER_CHOICE_MAP,
        )):
            return list(Interpose.SORT_ORDER_CHOICE_MAP[self.forwarded['interpose_type']])
        else:
            return []


class TagIDSelectWidget(LongListSelectWidget):
    def get_selected_options(self, tag_ids):
        tag_ids = [t for t in tag_ids if isinstance(t, int)]
        res = []

        if 0 in tag_ids:
            res.append((0, '全部',))
            tag_ids.remove(0)

        if tag_ids:
            tags = get_tags_by_ids(ids=tag_ids)
            for tag in tags:
                res.append(tag_option(tag))

        return res


class TagIDChoiceField(ChoiceField):
    def valid_value(self, value):
        tag_id = int(value)
        if tag_id == 0:
            return True
        else:
            tags = get_tags_by_ids(ids=[tag_id])
            if not tags:
                return False
            else:
                return True


class SortOrderSelectWidget(LongListSelectWidget):
    def get_selected_options(self, orders):
        instance = getattr(self.form, 'instance', None)
        if instance and instance.pk:
            assert isinstance(instance, Interpose)
            order_type = instance.SORT_ORDER_CHOICE_MAP[instance.interpose_type]
            orders = [instance.SORT_ORDER_CAST[instance.interpose_type](o) for o in orders]
            return [(o, order_type.getDesc(o)) for o in orders if o in order_type]
        else:
            return []


class ObjectIDChoiceField(ChoiceField):
    def valid_value(self, value):
        return True


class ObjectIDSelectWidget(LongListSelectWidget):
    def get_selected_options(self, selected_choices):
        selected_choices = [c for c in selected_choices if c]
        if not selected_choices:
            return []

        interpose = getattr(self.form.fields['interpose'], 'parent_instance', None)
        if not interpose:
            return []

        interpose_type = interpose.interpose_type

        if interpose_type in (
                INTERPOSE_TYPE.SERVICE_FILTER,
                INTERPOSE_TYPE.SERVICE_SEARCH
        ):
            object_ids = [int(c) for c in selected_choices]
            services = get_services_by_ids(ids=object_ids)
            res = []
            for service in services:
                res.append(service_option(service))
            return res
        elif interpose_type in (
                INTERPOSE_TYPE.DIARY_SEARCH,
                INTERPOSE_TYPE.DIARY_FILTER
        ):
            object_ids = [int(c) for c in selected_choices]
            diaries = get_diary_by_ids(ids=object_ids)
            res = []
            for diary in diaries:
                res.append(diary_option(diary))
            return res

        elif interpose_type in (
                INTERPOSE_TYPE.DOCTOR_SEARCH,
                INTERPOSE_TYPE.DOCTOR_FILTER,
                INTERPOSE_TYPE.OFFICER_SEARCH,
                INTERPOSE_TYPE.OFFICER_FILTER,
        ):
            object_ids = selected_choices
            if interpose_type == INTERPOSE_TYPE.DOCTOR_SEARCH:
                doctor_type = DOCTOR_TYPE.DOCTOR
            else:
                doctor_type = DOCTOR_TYPE.OFFICER
            doctors = get_doctors_by_ids(ids=object_ids)
            doctors = doctors.values()
            res = []
            for doctor in doctors:
                res.append(doctor_option(doctor))
            return res
        else:
            raise NotImplementedError


class InterposeForm(forms.ModelForm):
    class Meta:
        model = Interpose
        fields = ['interpose_type', 'keyword', 'city_tag_id', 'tag_id',
                  'sort_order', 'is_online',]
        labels = {
            'is_online': '是否生效'
        }

    def __init__(self, *args, **kwargs):
        super(InterposeForm, self).__init__(*args, **kwargs)
        self.fields['sort_order'].widget.form = self
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            self.fields['interpose_type'].disabled = True

    keyword = CharField(
        label='关键字',
        help_text='对于过滤不用填，对于搜索，填*表示全部(请三思)',
        required=False,
        max_length=Interpose._meta.get_field('keyword').max_length,
        widget=AdminTextInputWidget(attrs={
            'style': 'width:384px',
        })
    )

    interpose_type = ChoiceField(
        label='干预类型',
        choices=[t for t in INTERPOSE_TYPE],
        widget=autocomplete.ListSelect2(
            url='interpose-type-autocomplete',
        )
    )

    sort_order = ChoiceField(
        label='排序顺序',
        choices=Interpose.SORT_ORDERS,  # only for validation
        widget=SortOrderSelectWidget(
            url='sort-order-autocomplete',
            forward=['interpose_type']
        )
    )

    city_tag_id = TagIDChoiceField(
        label='城市/省份tag(医生机构请选省份)',
        widget=TagIDSelectWidget(
            url='city-tag-id-autocomplete'
        )
    )
    tag_id = TagIDChoiceField(
        label='部位/项目tag',
        widget=TagIDSelectWidget(
            url='item-tag-id-autocomplete'
        )
    )


class InterposeObjectForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(InterposeObjectForm, self).__init__(*args, **kwargs)
        self.fields['object_id'].widget.form = self

    object_id = ObjectIDChoiceField(
        widget=ObjectIDSelectWidget(
            attrs={'style':'width:512px'},
            url='object-id-autocomplete',
            forward=['interpose']
        )
    )


class InterposeObjectFormSet(forms.BaseInlineFormSet):
    def clean(self):
        super(InterposeObjectFormSet, self).clean()
        order_set = set()
        object_id_set = set()
        for form in self.forms:
            # check if deleted or empty form
            if 'DELETE' in form.cleaned_data and form.cleaned_data['DELETE']:
                continue
            elif any(('object_id' not in form.cleaned_data, 'order' not in form.cleaned_data)):
                continue

            if form.cleaned_data['order'] in order_set:
                raise ValidationError(
                    '重复的序号: %(dup_order)d',
                    code='duplicate entry',
                    params={'dup_order':form.cleaned_data['order']}
                )
            elif form.cleaned_data['object_id'] in object_id_set:
                raise ValidationError(
                    '重复的项目ID: %(dup_object_id)s',
                    code='duplicate entry',
                    params={'dup_object_id':form.cleaned_data['object_id']}
                )
            else:
                order_set.add(form.cleaned_data['order'])
                object_id_set.add(form.cleaned_data['object_id'])
