# coding=utf-8
from django.db import models
from django.forms import ValidationError
from gm_types.doris import INTERPOSE_TYPE
from gm_types.gaia import SERVICE_ORDER_TYPE as SOT, DOCTOR_ORDER_TYPE as DOT, DIARY_ORDER_TYPE
from gm_types.utils.enum import Enum
from ..utils.rpc_data import get_tags_by_ids
import json


class SERVICE_ORDER_CHOICES(Enum):
    DEFAULT = (SOT.DEFAULT,
               SOT.getDesc(SOT.DEFAULT),)
    DORIS_SMART = (SOT.DORIS_SMART,
                   SOT.getDesc(SOT.DORIS_SMART),)


class DOCTOR_ORDER_CHOICES(Enum):
    DEFAULT = (DOT.DEFAULT,'智能排序(搜索页)')  # different with DEFAULT2
    DEFAULT2 = (DOT.DEFAULT2,'智能排序(过滤)')

class DIARY_ORDER_CHOICES(Enum):
    DEFAULT = (DIARY_ORDER_TYPE.HOT,
               DIARY_ORDER_TYPE.getDesc(DIARY_ORDER_TYPE.HOT),)


class Interpose(models.Model):
    """
    人工干预记录
    """
    SERVICE_ORDER_CHOICES_LIST = list(SERVICE_ORDER_CHOICES)
    DOCTOR_ORDER_CHOICES_LIST = list(DOCTOR_ORDER_CHOICES)
    DIARY_ORDER_CHOICES_LIST = list(DIARY_ORDER_CHOICES)
    SORT_ORDERS = SERVICE_ORDER_CHOICES_LIST + DOCTOR_ORDER_CHOICES_LIST + DIARY_ORDER_CHOICES_LIST
    SORT_ORDER_CHOICE_MAP = {
        INTERPOSE_TYPE.SERVICE_FILTER: SERVICE_ORDER_CHOICES,
        INTERPOSE_TYPE.SERVICE_SEARCH: SERVICE_ORDER_CHOICES,
        INTERPOSE_TYPE.OFFICER_SEARCH: DOCTOR_ORDER_CHOICES,
        INTERPOSE_TYPE.OFFICER_FILTER: DOCTOR_ORDER_CHOICES,
        INTERPOSE_TYPE.DOCTOR_SEARCH: DOCTOR_ORDER_CHOICES,
        INTERPOSE_TYPE.DOCTOR_FILTER: DOCTOR_ORDER_CHOICES,
        INTERPOSE_TYPE.DIARY_FILTER: DIARY_ORDER_CHOICES,
        INTERPOSE_TYPE.DIARY_SEARCH: DIARY_ORDER_CHOICES,
    }
    SORT_ORDER_CAST = {
        INTERPOSE_TYPE.SERVICE_SEARCH: int,
        INTERPOSE_TYPE.SERVICE_FILTER: int,
        INTERPOSE_TYPE.OFFICER_SEARCH: int,
        INTERPOSE_TYPE.OFFICER_FILTER: int,
        INTERPOSE_TYPE.DOCTOR_SEARCH: int,
        INTERPOSE_TYPE.DOCTOR_FILTER: int,
        INTERPOSE_TYPE.DIARY_FILTER: str,
        INTERPOSE_TYPE.DIARY_SEARCH: str
    }

    class Meta:
        verbose_name = '人工干预'
        verbose_name_plural = '人工干预'
        unique_together = (
            ('interpose_type', 'sort_order', 'city_tag_id', 'tag_id', 'keyword'),
        )

    def __str__(self):
        s = '%d. 干预类型:%s, ' % (self.pk, INTERPOSE_TYPE.getDesc(self.interpose_type),)
        if self.keyword is not None:
            s += '关键字:%s, ' % self.keyword

        if self.city_tag_id==0:
            s += '城市tag:全部, '
        else:
            tags = get_tags_by_ids(ids=[self.city_tag_id,])
            s += '城市tag:%s, ' % tags[0]['name']

        if self.tag_id==0:
            s += '部位/项目tag:全部, '
        else:
            tags = get_tags_by_ids(ids=[self.tag_id,])
            s += '部位/项目tag:%s, ' % tags[0]['name']

        if self.interpose_type and self.sort_order is not None:
            order_type = self.SORT_ORDER_CHOICE_MAP[self.interpose_type]
            order = self.SORT_ORDER_CAST[self.interpose_type](self.sort_order)
            s += '排序顺序:%s' % order_type.getDesc(order)

        return s

    interpose_type = models.CharField(choices=INTERPOSE_TYPE, max_length=64)  # 干预类型
    keyword = models.CharField(null=True, max_length=128)  # 对于过滤，为null; 对于搜索，"*"表示全部
    city_tag_id = models.IntegerField()  # 0表示全部
    tag_id = models.IntegerField()  # 0表示全部
    sort_order = models.CharField(max_length=16)  # order_type全部转为字符串
    last_modified = models.DateTimeField(auto_now=True)
    object_ids = models.TextField()  # 最终列表的JSON表示

    is_online = models.BooleanField(default=False)

    def clean(self):
        super(Interpose, self).clean()

        if self.interpose_type in [
            INTERPOSE_TYPE.SERVICE_FILTER,
            INTERPOSE_TYPE.DIARY_FILTER,
            INTERPOSE_TYPE.DOCTOR_FILTER,
            INTERPOSE_TYPE.OFFICER_FILTER,
        ]:
            self.keyword = None

        elif self.interpose_type in [
            INTERPOSE_TYPE.SERVICE_SEARCH,
            INTERPOSE_TYPE.DOCTOR_SEARCH,
            INTERPOSE_TYPE.OFFICER_SEARCH,
            INTERPOSE_TYPE.DIARY_SEARCH
        ]:
            if self.keyword == '':
                raise ValidationError(
                    '人工干预搜索时，必须指定关键字',
                    code='missing params')

    def validate_unique(self, exclude=None):
        super(Interpose, self).validate_unique(exclude=exclude)

        dup_query = Interpose.objects.filter(
            interpose_type=self.interpose_type,
            sort_order=self.sort_order,
        )
        if self.interpose_type in [
            INTERPOSE_TYPE.SERVICE_SEARCH,
            INTERPOSE_TYPE.DOCTOR_SEARCH,
            INTERPOSE_TYPE.OFFICER_SEARCH,
            INTERPOSE_TYPE.DIARY_SEARCH,
        ]:
            if self.keyword != '*':
                dup_query = dup_query.filter(models.Q(keyword=self.keyword) | models.Q(keyword='*'))

        if self.city_tag_id != 0:
            dup_query = dup_query.filter(models.Q(city_tag_id=self.city_tag_id) | models.Q(city_tag_id=0))
        if self.tag_id != 0:
            dup_query = dup_query.filter(models.Q(tag_id=self.tag_id) | models.Q(tag_id=0))
        if self.pk:
            dup_query = dup_query.exclude(pk=self.pk)
        if dup_query.exists():
            dup_item = dup_query[0]
            raise ValidationError(
                '有重复或交叉条目: %(dup_entry)s',
                code='duplicate entry',
                params={'dup_entry':str(dup_item)})

    def update_obj_ids(self):
        interpose_objs = self.interpose_objects.order_by('order').all()

        # check if duplicate entry
        order_set = set()
        object_id_set = set()
        for obj in interpose_objs:
            if obj.order in order_set:
                raise ValueError('duplicate order: %d' % obj.order)
            elif obj.object_id in object_id_set:
                raise ValueError('duplicate object id: %s' % obj.object_id)
            else:
                order_set.add(obj.order)
                object_id_set.add(obj.object_id)

        cast_func = InterposeObject.OBJECT_ID_CAST[self.interpose_type]
        obj_id_list = [cast_func(obj.object_id) for obj in interpose_objs]
        self.object_ids = json.dumps(obj_id_list)
        self.save(update_fields=['object_ids'])


class InterposeObject(models.Model):
    class Meta:
        verbose_name = '人工干预排序结果'
        verbose_name_plural = '人工干预排序结果'

    OBJECT_ID_CAST = {
        INTERPOSE_TYPE.SERVICE_SEARCH: int,
        INTERPOSE_TYPE.SERVICE_FILTER: int,
        INTERPOSE_TYPE.DOCTOR_SEARCH: str,
        INTERPOSE_TYPE.OFFICER_SEARCH: str,
        INTERPOSE_TYPE.OFFICER_FILTER: str,
        INTERPOSE_TYPE.DOCTOR_FILTER: str,
        INTERPOSE_TYPE.DIARY_FILTER: int,
        INTERPOSE_TYPE.DIARY_SEARCH: int
    }

    interpose = models.ForeignKey(Interpose, related_name='interpose_objects')
    order = models.IntegerField(default=0)
    object_id = models.CharField(max_length=64)
