# -*- coding=utf-8
import time
from django.db import models
from django.db.models import Max
from django.contrib.auth.models import User
from django.db.models import Q
from gm_types.gaia import PLATFORM_CHANNEL
import datetime
from django.conf import settings

from api.tool.common_tool import check_platform
from rpc.tool.protocol import gm_protocol
from .area import Province, City, Region
from .service import Service
from .special import Special
from .tag import Tag
from .coupon import ChannelGift
from api.tool.datetime_tool import get_timestamp_or_none
from gm_upload import ImgUrlField, IMG_TYPE
from gm_types.gaia import PUSH_USER_TYPE
from gm_types.gaia import PUSHCOUPON_STATUS, PUSHCOUPON_USER_STATUS, PUSHCOUPON_USER_TYPE
from polymer.models import Polymer
from relation.models import UserTagRelation
from gm_types.gaia import USER_TAG_CHOICES


# todo 规整所有类型ID啊，不要新增一个类型，代码又得到处改啊 180120
TOPIC_IMG_HEADER = 'https://heras.igengmei.com/slide/2016/11/15/e54318d570'
DIARY_IMG_HEADER = 'https://heras.igengmei.com/slide/2016/11/15/461e631886'
TAG_IMG_HEADER = 'https://heras.igengmei.com/slide/2016/11/15/3bd1b577b1'
URL_IMG_HEADER = 'https://heras.igengmei.com/slide/2016/11/15/c0dd9f67e7'
SERVICE_IMG_HEADER = 'https://heras.igengmei.com/slide/2016/11/15/0eec96a8ec'
SPECIAL_IMG_HEADER = 'https://heras.igengmei.com/slide/2016/11/15/1d3358108b'


class PushTask(models.Model):
    class Meta:
        verbose_name = u'消息推送'
        verbose_name_plural = u'消息推送'
        db_table = 'api_pushtask'
        app_label = 'api'

    to_android = models.BooleanField(verbose_name=u'Android', default=False)
    to_ios = models.BooleanField(verbose_name=u'iOS', default=False)
    provinces = models.ManyToManyField(Province, default=None, blank=True,
                                       help_text=u'不选的话，默认为推送给所有人',
                                       verbose_name=u'推送的省份')
    alert = models.CharField(verbose_name=u'推送内容', max_length=64)
    topic_id = models.IntegerField(default=None, blank=True, null=True, verbose_name=u'跳转的话题')
    service = models.ForeignKey(Service, default=None, blank=True, null=True, verbose_name=u'跳转的福利')
    special = models.ForeignKey(Special, default=None, blank=True, null=True, verbose_name=u'跳转的专题')
    diary_id = models.IntegerField(default=None, blank=True, null=True, verbose_name=u'跳转的日记本')
    tag = models.ForeignKey(Tag, default=None, blank=True, null=True, verbose_name=u'跳转的圈子')
    eta = models.DateTimeField(verbose_name=u'推送时间', blank=True, null=True, default=None)
    created_time = models.DateTimeField(verbose_name=u'创建时间', auto_now_add=True)
    is_finished = models.BooleanField(verbose_name=u'是否已完成推送', default=False)
    creator = models.ForeignKey(User, verbose_name=u'创建的用户', related_name=u'created_push_tasks', blank=True,
                                null=True, default=None)
    approver = models.ForeignKey(User, verbose_name=u'审核通过的用户', related_name=u'applied_push_tasks',
                                 blank=True, null=True, default=None)
    push_to_home = models.BooleanField(verbose_name=u'推送到APP首页', default=False)
    push_to_zone = models.BooleanField(verbose_name=u'推送到圈子首页', default=False)
    article_id = models.IntegerField(default=None, blank=True, null=True, verbose_name=u'跳转的专栏')

    is_activity_push = models.BooleanField(verbose_name=u'是否是活动推送', default=False)
    banner = ImgUrlField(img_type=IMG_TYPE.BANNER, max_length=120, verbose_name='banner', blank=True, default='')
    url = models.CharField(verbose_name=u'推送到网页', max_length=256)
    activity_id = models.IntegerField(verbose_name=u'免费活动', null=True, blank=True)
    zhibo_user = models.ForeignKey(User, verbose_name=u'跳转的主播', null=True, blank=True, default=None)

    # 精准推送添加 2017-03-30
    city = models.ManyToManyField(City, verbose_name=u'推送城市', through='PushtaskCity')
    region = models.ManyToManyField(Region, verbose_name=u'推送大区', through='PushtaskRegion')
    push_user_type = models.IntegerField(verbose_name=u'推送用户类型', default=0, max_length=2, choices=PUSH_USER_TYPE)
    push_tags = models.ManyToManyField(Tag, verbose_name=u'推送tag', through='PushtaskTag', related_name=u'push_tags')
    question_id = models.IntegerField(u'跳转的问题', default=None, null=True, blank=True)
    answer_id = models.IntegerField(u'跳转的回答', default=None, null=True, blank=True)

    #推送新加聚合页
    polymer = models.ManyToManyField(Polymer, verbose_name=u'关联的聚合页', default=None, max_length=64, through='PushtaskPolymer')
    def __unicode__(self):
        return u'{}'.format(self.alert)

    @property
    def push_history_data(self):
        # TODO: TALOS MIGRATE
        from talos.models.topic import Activity

        return {
            'alert': self.alert,
            'topic_id': self.topic_id,
            'service_id': self.service_id,
            'special_id': self.special_id,
            'special_type': self.special and self.special.type or '',
            'diary_id': self.diary_id,
            'question_id': self.question_id,
            'answer_id': self.answer_id,
            'eta': get_timestamp_or_none(self.eta),
            'push_to_home': self.push_to_home,
            'push_to_zone': self.push_to_zone,
            'banner': self.banner,
            'id': self.id,
            'url': self.url,
            'tag': {
                'id': self.tag and self.tag.id or None,
                'name': self.tag and self.tag.name or '',
            },
            'activity': {
                'id': self.activity_id or None,
                # 'title': self.activity and self.activity.title or None,
                'title': Activity.objects.get(id=self.activity_id).title if self.activity_id else None,
            },
        }

    def to_dict(self):
        if self.banner:
            type = 2
        else:
            type = 1

        return {
            'id': self.id,
            'title': self.alert,
            'content': self.alert,
            'type': type,
            'create_time': self.eta.strftime('%Y-%m-%d  %H:%M:%S'),
            'pic': self.banner,
            'url': self.jump_url,
            'imgheader': self.imgheader,
            "is_view": True,
            'user': 'None'
        }

    @property
    def imgheader(self):
        if self.topic_id:
            return TOPIC_IMG_HEADER
        elif self.diary_id:
            return DIARY_IMG_HEADER
        elif self.tag:
            return TAG_IMG_HEADER
        elif self.special:
            return SERVICE_IMG_HEADER
        elif self.service:
            return SERVICE_IMG_HEADER
        elif self.activity_id:
            return SPECIAL_IMG_HEADER
        else:
            return URL_IMG_HEADER

    @property
    def jump_url(self):
        if self.topic_id:
            return gm_protocol.get_topic_detail(id=self.topic_id)
        elif self.tag:
            return gm_protocol.get_zone_detail(id=self.tag_id, title=self.tag.name)
        elif self.diary_id:
            return gm_protocol.get_diary_detail(id=self.diary_id)
        elif self.url:
            if self.url.startswith("gengmei://"):
                return self.url
            return gm_protocol.get_webview(url=self.url)
        elif self.service:
            return gm_protocol.get_service_detail(id=self.service_id)
        elif self.special_id:
            return gm_protocol.get_service_special_list(id=self.special_id)
        elif self.activity_id:
            return gm_protocol.get_activity_detail(self.activity_id)
        elif self.article_id:
            return gm_protocol.get_article(self.article_id)
        elif self.question_id:
            return gm_protocol.get_question_detail(question_id=self.question_id)
        elif self.answer_id:
            return gm_protocol.get_answer_list(answer=self.answer_id)

    @classmethod
    def get_community_query(cls, platform, time):
        if platform == PLATFORM_CHANNEL.IOS:
            q = Q(to_ios=1)
        else:
            q = Q(to_android=1)
        now = datetime.datetime.now()
        q = q & Q(eta__gte=time) & Q(eta__lte=now) & Q(approver__isnull=False)
        q = q & Q(service=None) & Q(special=None) & Q(activity_id=None)
        return q

    @classmethod
    def get_choose_query(cls, platform, time):
        if platform == PLATFORM_CHANNEL.IOS:
            q = Q(to_ios=1)
        else:
            q = Q(to_android=1)
        now = datetime.datetime.now()
        q = q & Q(eta__gte=time) & Q(eta__lte=now) & Q(approver__isnull=False)
        q = q & Q(url='') & Q(topic_id=None) & Q(diary_id=None) & Q(tag=None) & Q(zhibo_user__isnull=True)
        return q

    @classmethod
    def get_user_choose_query(cls, user, platform, start_num=0, count=10):
        time = user.date_joined
        platform = check_platform(platform)
        tasks = PushTask.objects.filter(PushTask.get_choose_query(platform, time)).order_by('-id')
        task_ids = tasks.values('alert').annotate(max_id=Max('id')).order_by('-max_id')
        task_ids = task_ids[start_num:start_num + count].values_list('max_id', flat=True)
        tasks = PushTask.objects.filter(id__in=list(task_ids)).order_by('-id')

        return tasks

    @classmethod
    def get_pushuser_by_polymer(cls, polymer_ids=None):
        if polymer_ids:
            tags_id_list = Polymer.objects.filter(pk__in=polymer_ids).values_list('tags', flat=True) #去重
            tags_id_list = list(set((filter(None, tags_id_list))))
            user_ids = UserTagRelation.objects.filter(related_tag__in=tags_id_list, tag_type=USER_TAG_CHOICES.FOLLOWED).values_list('user', flat=True)
        return {'user': list(user_ids)}

    @classmethod
    def get_user_community_query(cls, user, platform, start_num=0, count=10):
        time = user.date_joined
        platform = check_platform(platform)
        tasks = PushTask.objects.filter(PushTask.get_community_query(platform, time)).order_by('-id')
        task_ids = tasks.values('alert').annotate(max_id=Max('id')).order_by('-max_id')
        task_ids = task_ids[start_num:start_num + count].values_list('max_id', flat=True)
        tasks = PushTask.objects.filter(id__in=list(task_ids)).order_by('-id')

        return tasks

    @classmethod
    def _get_push_query(cls, platform):
        if platform == PLATFORM_CHANNEL.IOS:
            q = Q(to_ios=1)
        else:
            q = Q(to_android=1)
        now = datetime.datetime.now()
        q = q & Q(eta__lte=now) & Q(approver__isnull=False) & Q(zhibo_user__isnull=True)
        return q

    @classmethod
    def _get_city_query(cls, city_id):

        # 通过城市 id 选出PushTask对应的大区以及对应的city_id

        if not city_id:
            return Q()

        if city_id != "worldwide":
            query = Q(city__id=city_id)
            city_regions = []
            for region in Region.objects.all():
                region_cities = [item.id for item in region.cities()]
                if city_id in region_cities:
                    city_regions.append(region.id)

            query |= Q(region__in=city_regions)
        else:
            query = None

        # 为了兼容历史记录，让09-26之前的推送消息依然可见
        time_query = Q(eta__lte=datetime.datetime.strptime("2018-09-26", "%Y-%m-%d"))

        if not query:
            return ((Q(city__isnull=True) & Q(region__isnull=True)) | time_query)

        return ((query) | (Q(city__isnull=True) & Q(region__isnull=True)) | time_query)

    @classmethod
    def get_index_push_query(cls, platform, start_num=0, count=10, city_id=None):
        platform = check_platform(platform)
        query = PushTask._get_push_query(platform) & (cls._get_city_query(city_id))
        tasks = PushTask.objects.filter(query).order_by('-id')
        task_ids = tasks.values('alert').annotate(max_id=Max('id')).order_by('-eta')
        task_ids = task_ids[start_num: start_num + count].values_list('max_id', flat=True)
        tasks = PushTask.objects.filter(id__in=list(task_ids)).order_by('-eta')

        return tasks

    @property
    def imgheader_v2(self):
        # 新增推送内容后需要update该方法
        if self.topic_id or self.activity_id or self.url or self.article_id:
            return settings.ACTIVITY_IMG_HEADER_V2
        elif self.diary_id or self.question_id or self.answer_id:
            return settings.DIARY_IMG_HEADER_V2
        elif self.tag:
            return settings.TAG_IMG_HEADER_V2
        elif self.special or self.service:
            return settings.SPECIAL_IMG_HEADER_V2
        elif self.zhibo_user:
            return settings.LIVE_IMG_HEADER_V2
        else:
            # 返回默认图标
            return settings.LIVE_IMG_HEADER_V2

    @property
    def toptitle(self):
        # 新增推送内容后需要update该方法
        if self.topic_id or self.activity_id or self.url or self.article_id:
            return u'社区活动'
        elif self.diary_id:
            return u'日记本'
        elif self.tag:
            return u'标签'
        elif self.special or self.service:
            return u'美购专场'
        elif self.zhibo_user:
            return u'直播'
        elif self.question_id or self.answer_id:
            return u'问答'
        else:
            return ''

    def to_dict2(self):
        """
        已有to_dict方法，但返回数据略有不同，故新增
        """
        if self.banner:
            type = 2
        else:
            type = 1

        return {
            'id': self.id,
            'title': self.alert,
            'content': self.alert,
            'type': type,
            'create_time': self.eta.strftime('%Y-%m-%d  %H:%M:%S'),
            'time_stamp': int(time.mktime(self.eta.timetuple())),
            'pic': self.banner,
            'url': self.jump_url,
            'imgheader': self.imgheader_v2,
            "is_view": True,
            'user': 'None',
            'top_title': self.toptitle,
            'unread_count': 0,
        }


class PushtaskRegion(models.Model):
    class Meta:
        verbose_name = '推送大区'
        app_label = 'api'

    pushtask = models.ForeignKey(PushTask, verbose_name=u'关联推送')
    region = models.ForeignKey(Region, verbose_name=u'关联大区')


class PushtaskCity(models.Model):
    class Meta:
        verbose_name = '推送城市'
        app_label = 'api'

    pushtask = models.ForeignKey(PushTask, verbose_name=u'关联推送')
    city = models.ForeignKey(City, verbose_name=u'关联城市')


class PushtaskTag(models.Model):
    class Meta:
        verbose_name = '推送tag'
        app_label = 'api'

    pushtask = models.ForeignKey(PushTask, verbose_name=u'关联推送')
    tag = models.ForeignKey(Tag, verbose_name=u'关联tag')


class PushtaskPolymer(models.Model):
    class Meta:
        verbose_name = '问答推送聚合页'
        app_label = 'api'

    pushtask = models.ForeignKey(PushTask, verbose_name=u'关联推送')
    polymer = models.ForeignKey(Polymer, verbose_name=u'关联聚合页')


class PushtaskQAAlert(models.Model):
    class Meta:
        verbose_name = '问答推送是否存在推送内容'
        db_table = 'api_pushtask_qa_alert'
        app_label = 'api'

    pushtask_qa_id = models.IntegerField(verbose_name=u'关联的问题和回答的推送')
    have_alert = models.BooleanField(verbose_name=u'是否有推送内容', default=True)


class PushCoupon(models.Model):
    class Meta:
        verbose_name = '美券推送'
        app_label = 'api'

    name = models.CharField(verbose_name=u'推送名称', max_length=64)
    eta = models.DateTimeField(verbose_name=u'预定推送时间')
    gift = models.ForeignKey(ChannelGift)
    push_popup = models.BooleanField(verbose_name=u'首页弹窗')
    popup_img = ImgUrlField(img_type=IMG_TYPE.GREETINGPOPUP, verbose_name=u'图片地址', max_length=256)
    push_alert = models.BooleanField(verbose_name=u'消息推送')
    alert_msg = models.CharField(verbose_name=u'推送内容', max_length=64)
    status = models.IntegerField(verbose_name=u'状态', choices=PUSHCOUPON_STATUS, default=PUSHCOUPON_STATUS.DEFAULT)
    create_user = models.ForeignKey(User, verbose_name=u'创建用户')
    updated_time = models.DateTimeField(u'更新时间', auto_now=True)
    created_time = models.DateTimeField(u'创建时间', auto_now_add=True)
    market_id = models.TextField(verbose_name=u'营销标签id列表')


class PushCouponUser(models.Model):
    class Meta:
        verbose_name = '美券推送用户'
        app_label = 'api'

    push_coupon = models.ForeignKey(PushCoupon, related_name='user')
    user = models.ForeignKey(User)
    get_coupon_time = models.DateTimeField(verbose_name=u'美券领取时间', blank=True, null=True, default=None)
    push_coupon_status = models.IntegerField(verbose_name=u'用户领取状态', choices=PUSHCOUPON_USER_STATUS, default=PUSHCOUPON_USER_STATUS.DEFAULT)
    has_show_popup = models.BooleanField(verbose_name=u'是否展示过弹窗', default=False)
    user_type = models.IntegerField(verbose_name=u'用户类型', choices=PUSHCOUPON_USER_TYPE, default=PUSHCOUPON_USER_TYPE.DEFAULT)


class PushUserTag(models.Model):
    class Meta:
        verbose_name = '推送关联tag的用户'
        db_table = 'user_push_tag'

    id = models.IntegerField(u'id', primary_key=True)
    device_id = models.TextField(u'设备id')
    cl_type = models.TextField(u'设备类型')
    tag_id = models.TextField(u'标签id')

