# -*- coding: UTF-8 -*-
import datetime
import json
from django.db.models import Q
from gm_dataquery.dataquery import DataBuilder, DataSQLQuery
from gm_dataquery.db import DB
from gm_types.error import ERROR

from gm_types.gaia import (
    SLIDE_PAYMENT_TYPE,
    SLIDE_USER_TYPE,
    SERVICE_HOME_OPERATION,
    SERVICE_DISPLAY_PORT,
    FONT_COLOR,
    SERVICEHOME_OPERATION_POSITION
)


from api.models import (
    SpecialItem,
    ServiceFilter,
    CategoryGadget,
    NewCategory,
    ServiceHomeBackground,
    ServiceHomeOperation,
    ServiceRelatedOperation,
    Region)
from launch.models import ServiceConfigureRelevant, ServiceConfigureRelationCity, ServiceConfigureRelationRegion
from rpc.exceptions import GaiaRPCFaultException
from rpc.tool.dict_mixin import to_dict



class RecommendDB(DataBuilder):
    def getval_service__id(self, obj):
        return obj.service.id

    def getval_service__name(self, obj):
        return obj.service.name

    def getval_service__is_online(self, obj):
        if obj.service.is_online:
            return '是'
        else:
            return '否'

    def getval_pre_payment_price(self, obj):
        service = obj.service
        pre_payment_price = service.pre_payment_price
        if service.is_multiattribute:
            pre_payment_price = service.items.aggregate(c=Min('pre_payment_price')).get('c')
        return pre_payment_price

    def getval_gengmei_price(self, obj):
        service = obj.service
        gengmei_price = service.gengmei_price
        if service.is_multiattribute:
            gengmei_price = service.items.aggregate(c=Min('gengmei_price')).get('c')
        return gengmei_price

    def getval_discount(self, obj):
        service = obj.service
        discount = service.discount
        if service.is_multiattribute:
            discount = service.items.aggregate(c=Min('discount')).get('c')
        return discount

    def getval_is_online(self, obj):
        return obj.service.is_online


class RecommendDQ(DataSQLQuery):
        model = SpecialItem
        data_model = RecommendDB


class ServiceFilterDB(DataBuilder):
    pass


@DB
class ServiceFilterDQ(DataSQLQuery):
        model = ServiceFilter
        data_model = ServiceFilterDB


class CategoryGadgetDB(DataBuilder):
    def getval_image_data(self, obj, need_escape=False):
        return json.loads(obj.image_data)


@DB
class CategoryGadgetDQ(DataSQLQuery):
    model = CategoryGadget
    data_model = CategoryGadgetDB


class NewCategoryDB(DataBuilder):
    def getval_cities_name(self, obj):
        return [x.name for x in obj.cities.all()]

    def getval_regions_name(self, obj):
        return [x.name for x in obj.regions.all()]


@DB
class NewCategoryDQ(DataSQLQuery):
    model = NewCategory
    data_model = NewCategoryDB

    def create(self, **kwargs):
        tags = kwargs.pop('tags')
        cities = kwargs.pop('cities')
        regions = kwargs.pop('regions')
        obj = self.model.objects.create(**kwargs)
        obj.tags = tags
        obj.cities = cities
        obj.regions = regions
        return to_dict(obj)


class ServiceHomeBackgroundDB(DataBuilder):
    pass


@DB
class ServiceHomeBackgroundDQ(DataSQLQuery):
    model = ServiceHomeBackground
    data_model = ServiceHomeBackgroundDB


class ServiceHomeOperationDB(DataBuilder):
    def getval_details(self, obj, need_escape=False):
        return json.loads(obj.details)

    def getval_cities_name(self, obj):
        return [x.name for x in obj.cities.all()]

    def getval_regions_name(self, obj):
        return [x.name for x in obj.regions.all()]

    def getval_operation_type_desc(self, obj):
        return SERVICE_HOME_OPERATION.getDesc(obj.operation_type)

    def getval_user_type_desc(self, obj):
        return SLIDE_USER_TYPE.getDesc(obj.user_type)

    def getval_payment_type_desc(self, obj):
        return SLIDE_PAYMENT_TYPE.getDesc(obj.payment_type)

    def getval_position(self, obj):
        return sorted(list(ServiceRelatedOperation.objects.filter(servicehome_id=obj.id).values_list("position", flat=True)))


@DB
class ServiceHomeOperationDQ(DataSQLQuery):
    model = ServiceHomeOperation
    data_model = ServiceHomeOperationDB

    def filter_position(self, srch_key, srch_val, regex=False):
        service_home_ids = ServiceRelatedOperation.objects.filter(position__in=srch_val).values_list('servicehome_id', flat=True)
        if service_home_ids:
            return Q(id__in = service_home_ids)
        return Q()


class ServiceConfigureRelevantDB(DataBuilder):
    def getval_cities(self, obj):
        return list(ServiceConfigureRelationCity.objects.filter(service_configure_relevant_id=obj.id).values_list('city_id', flat=True))

    def getval_regions(self, obj):
        return list(ServiceConfigureRelationRegion.objects.filter(service_configure_relevant_id=obj.id).values_list('region_id', flat=True))


@DB
class ServiceConfigureRelevantDQ(DataSQLQuery):
    model = ServiceConfigureRelevant
    data_model = ServiceConfigureRelevantDB

    def create(self, **kwargs):
        cities = kwargs.pop('cities')
        # regions = kwargs.pop('regions')
        kwargs['special_id'] = kwargs.pop('special')
        start_time = kwargs.get('start_time', '')
        end_time = kwargs.get('end_time', '')
        if self.model.objects.filter(title=kwargs['title'], event_type=kwargs['event_type']).exists():
            raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message=u'标题已存在,不能重复配置', data=None)
        now = str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
        if start_time < now or end_time < now:
            raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message=u'开始时间, 结束时间不能小于当前编辑时间', data=None)
        if end_time <= start_time:
            raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message=u'结束时间不能小于开始时间', data=None)
        obj = self.model.objects.create(**kwargs)
        if cities:
            ServiceConfigureRelationCity.objects.bulk_create([
                ServiceConfigureRelationCity(
                    city_id=city,
                    service_configure_relevant=obj,
                )
                for city in cities
            ])

        # if regions:
        #     ServiceConfigureRelationRegion.objects.bulk_create([
        #         ServiceConfigureRelationRegion(
        #             region_id=region,
        #             service_configure_relevant=obj,
        #         )
        #         for region in regions
        #     ])

        return to_dict(obj)

    def update(self, updates, **kwargs):
        _pk = kwargs.get("id", 0)
        service_configure_relevant_obj = self.model.objects.get(pk=_pk)
        title = updates.get('title','')
        updates['special_id'] = updates.pop('special')
        # regions = updates.get('regions','')
        cities = updates.get('cities','')
        start_time = updates.get('start_time','')
        end_time = updates.get('end_time','')
        now = str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
        if title:
            q = Q(title=title) & ~Q(id=_pk)
            service_configure_relevant = ServiceConfigureRelevant.objects.filter(q).order_by('-id').first()
            if service_configure_relevant:
                raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message=u'标题已存在,不能重复配置', data=None)
        if start_time and start_time != str(service_configure_relevant_obj.start_time.strftime("%Y-%m-%d %H:%M:%S")):
            if start_time < now:
                raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message=u'开始时间不能小于当前编辑时间', data=None)
        if end_time and end_time != str(service_configure_relevant_obj.end_time.strftime("%Y-%m-%d %H:%M:%S")):
            if end_time < now:
                raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message=u'结束时间不能小于当前编辑时间', data=None)
        if end_time <= start_time:
            raise GaiaRPCFaultException(error=ERROR.UNIVERSAL, message=u'结束时间不能小于开始时间', data=None)

        # if regions != '':
        #     new_region = set(Region.objects.filter(id__in=regions))
        #     region_id = list(ServiceConfigureRelationRegion.objects.filter(service_configure_relevant_id=_pk).values_list('region_id', flat=True))
        #     old_region = set(Region.objects.filter(id__in=region_id))
        #     for region in (new_region - old_region):
        #         ServiceConfigureRelationRegion.objects.get_or_create(service_configure_relevant_id=_pk, region=region)
        #     ServiceConfigureRelationRegion.objects.filter(service_configure_relevant=_pk, region__in=(old_region - new_region)).delete()

        if cities != '':
            old_cities = set(ServiceConfigureRelationCity.objects.filter(service_configure_relevant_id=_pk))
            new_cities = set(ServiceConfigureRelationCity.objects.get_or_create(city_id=item,
                                                            service_configure_relevant_id=_pk
                                                            )[0] for item in cities)
            for item in (old_cities - new_cities):
                item.delete()

        return super(ServiceConfigureRelevantDQ.sqlquery, self).update(updates, **kwargs)
