# -*- coding: UTF-8 -*-
import datetime

from django.db.models import Q
from gm_dataquery.db import DB
from gm_dataquery.dataquery import DataSQLQuery, DataBuilder
from gm_types.error import ERROR
from gm_types.gaia import BASE_BAR_CONFIG, SECKILL_STATUS
from gm_dataquery.dict_mixin import to_dict
from rpc.exceptions import GaiaRPCFaultException

from api.models.icon import Icon, ServiceJumpConfig, IndexDefaultBar


def judge_overlap_time(time_slot_list, start_time, end_time):
    """判断时间段是否有重复"""
    for time_slot in time_slot_list:
        s_time, e_time = time_slot.get("start_time"), time_slot.get("end_time")
        if start_time < s_time and end_time < s_time:
            continue
        if start_time > e_time and end_time > e_time:
            continue

        return False
    return True


class IconDB(DataBuilder):
    pass


@DB
class IconDQ(DataSQLQuery):
    model = Icon
    data_model = IconDB


class ServiceJumpConfigDB(DataBuilder):
    def getval_status_name(self, obj):
        if not obj.is_online:
            return u"---"
        if obj.start_time > datetime.datetime.now():
            return u"未开始"
        if obj.end_time < datetime.datetime.now():
            return u"已结束"
        else:
            return u"进行中"

@DB
class ServiceJumpConfigDQ(DataSQLQuery):
    model = ServiceJumpConfig
    data_model = ServiceJumpConfigDB

    @classmethod
    def create(cls, *args, **kwargs):

        start_time = datetime.datetime.strptime(kwargs.get("start_time"), "%Y-%m-%d %H:%M:%S")
        end_time = datetime.datetime.strptime(kwargs.get("end_time"), "%Y-%m-%d %H:%M:%S")
        time_list = ServiceJumpConfig.objects.filter(is_online=True).values("start_time", "end_time")
        status = judge_overlap_time(time_slot_list=time_list, start_time=start_time, end_time=end_time)
        config_record = ServiceJumpConfig.objects.filter(is_online=True, name=kwargs.get("name"))
        if config_record:
            raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message='名称有重复', data=None)
        if not status and kwargs.get("is_online"):
            raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message='时间间隔有重叠', data=None)
        if start_time >= end_time:
            raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message='开始时间应小于结束时间', data=None)

        config = ServiceJumpConfig.objects.create(**kwargs)
        return to_dict(config)

    @classmethod
    def update(cls, updates, **kwargs):
        jump_id = int(kwargs.get("id"))
        jump_info = ServiceJumpConfig.objects.filter(id=jump_id).first()
        start_time = datetime.datetime.strptime(updates.get("start_time"),
                                                "%Y-%m-%d %H:%M:%S") if "start_time" in updates else jump_info.start_time
        end_time = datetime.datetime.strptime(updates.get("end_time"),
                                              "%Y-%m-%d %H:%M:%S") if "end_time" in updates else jump_info.end_time
        jump_info.is_online = updates.get("is_online") if "is_online" in updates else jump_info.is_online
        jump_info.name = updates.get("name") if "name" in updates else jump_info.name
        if jump_info.is_online:
            time_list = ServiceJumpConfig.objects.filter(Q(is_online=True)).filter(~Q(id=jump_id)).values("start_time",
                                                                                                      "end_time")
            status = judge_overlap_time(time_slot_list=time_list, start_time=start_time,
                                        end_time=end_time)

            config_record = ServiceJumpConfig.objects.filter(Q(is_online=True, name=jump_info.name)).filter(~Q(id=jump_id))
            if config_record:
                raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message='名称有重复', data=None)

            if not status:
                raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message='时间间隔有重叠', data=None)

            if start_time >= end_time:
                raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message='开始时间应小于结束时间', data=None)

        jump_info.start_time = start_time
        jump_info.end_time = end_time
        jump_info.url = updates.get("url") if "url" in updates else jump_info.url
        jump_info.save()

    def filter_start_time(self, srch_key, srch_val, regex=True):

        return self._qry_time_range(srch_key, srch_val, regex)

    def filter_end_time(self, srch_key, srch_val, regex=True):

        return self._qry_time_range(srch_key, srch_val, regex)

    def filter_name(self, srch_key, srch_val, regex=True):

        return Q(name=srch_val)

    def filter_status_name(self, srch_key, srch_val, regex=True):
        if int(srch_val) == SECKILL_STATUS.BEFORE or str(srch_val) == SECKILL_STATUS.BEFORE:
            return Q(is_online=True, start_time__gte=datetime.datetime.now())
        if int(srch_val) == SECKILL_STATUS.UNDERWAY or str(srch_val) == SECKILL_STATUS.UNDERWAY:
            return Q(is_online=True, start_time__lte=datetime.datetime.now(), end_time__gte=datetime.datetime.now())
        if int(srch_val) == SECKILL_STATUS.AFTER or str(srch_val) == SECKILL_STATUS.AFTER:
            return Q(is_online=True, end_time__lte=datetime.datetime.now())


class IndexDefaultBarDB(DataBuilder):
    def getval_bar_type_name(self, obj):
        return BASE_BAR_CONFIG.getDesc(obj.bar_type)

    def getval_status_name(self, obj):
        if not obj.is_online:
            return u"---"
        if obj.start_time > datetime.datetime.now():
            return u"未开始"
        if obj.end_time < datetime.datetime.now():
            return u"已结束"
        else:
            return u"进行中"

@DB
class IndexDefaultBarDQ(DataSQLQuery):
    model = IndexDefaultBar
    data_model = IndexDefaultBarDB

    @classmethod
    def create(cls, *args, **kwargs):

        start_time = datetime.datetime.strptime(kwargs.get("start_time"), "%Y-%m-%d %H:%M:%S")
        end_time = datetime.datetime.strptime(kwargs.get("end_time"), "%Y-%m-%d %H:%M:%S")
        time_list = IndexDefaultBar.objects.filter(is_online=True).values("start_time", "end_time")
        status = judge_overlap_time(time_slot_list=time_list, start_time=start_time, end_time=end_time)
        if not status and kwargs.get("is_online"):
            raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message='时间间隔有重叠', data=None)
        if start_time >= end_time:
            raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message='开始时间应小于结束时间', data=None)

        bar = IndexDefaultBar.objects.create(**kwargs)
        return to_dict(bar)

    @classmethod
    def update(cls, updates, **kwargs):
        bar_id = int(kwargs.get("id"))
        bar_info = IndexDefaultBar.objects.filter(id=bar_id).first()
        start_time = datetime.datetime.strptime(updates.get("start_time"),
                                                "%Y-%m-%d %H:%M:%S") if "start_time" in updates else bar_info.start_time
        end_time = datetime.datetime.strptime(updates.get("end_time"),
                                              "%Y-%m-%d %H:%M:%S") if "end_time" in updates else bar_info.end_time
        bar_info.is_online = updates.get("is_online") if "is_online" in updates else bar_info.is_online
        if bar_info.is_online:
            time_list = IndexDefaultBar.objects.filter(Q(is_online=True)).filter(~Q(id=bar_id)).values("start_time", "end_time")
            status = judge_overlap_time(time_slot_list=time_list, start_time=start_time,
                                        end_time=end_time)
            if not status:
                raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message='时间间隔有重叠', data=None)

        bar_info.start_time = start_time
        bar_info.end_time = end_time
        bar_info.bar_type = updates.get("bar_type") if "bar_type" in updates else bar_info.bar_type
        bar_info.save()

    def filter_start_time(self, srch_key, srch_val, regex=True):

        return self._qry_time_range(srch_key, srch_val, regex)

    def filter_end_time(self, srch_key, srch_val, regex=True):

        return self._qry_time_range(srch_key, srch_val, regex)

    def filter_bar_type_name(self, srch_key, srch_val, regex=False):

        return Q(bar_type=int(srch_val))

    def filter_status_name(self, srch_key, srch_val, regex=True):
        if int(srch_val) == SECKILL_STATUS.BEFORE or str(srch_val) == SECKILL_STATUS.BEFORE:
            return Q(is_online=True, start_time__gte=datetime.datetime.now())
        if int(srch_val) == SECKILL_STATUS.UNDERWAY or str(srch_val) == SECKILL_STATUS.UNDERWAY:
            return Q(is_online=True, start_time__lte=datetime.datetime.now(), end_time__gte=datetime.datetime.now())
        if int(srch_val) == SECKILL_STATUS.AFTER or str(srch_val) == SECKILL_STATUS.AFTER:
            return Q(is_online=True, end_time__lte=datetime.datetime.now())