# coding:utf-8

from __future__ import unicode_literals

import dateutil.parser as parser
import time
import datetime

from api.models import Merchant, Coupon, GiftToCoupon

from django.core.management import BaseCommand
from rpc.tool.error_code import CODES

from search.utils.conversation import search_conversation_from_es
from services.unread.stat import UserUnread

from api.models.types import MESSAGE_TYPE
from hippo.models import MerchantRelevance, Doctor
from gm_types.gaia import DOCTOR_TYPE, COUPON_TYPES, COUPON_DISTRIBUTION_STATUS
from gm_types.msg import CONVERSATION_ORDER, CONVERSATION_TYPE
from gm_types.trade import COUPON_TIME_TYPE
from message.views.message import internal_message_send
from api.models.message import ConversationUserStatus

from rpc.exceptions import RPCPermanentError


def get_conversations_v3(user_ids, offset, size, order_by=CONVERSATION_ORDER.LAST_REPLY_TIME,
                               last_reply_time_start=None, last_reply_time_end=None, reply_status=None,
                               is_star=None, user_id=None, user_last_name=None, comment=None):
    """
    获取会话列表， 与v2不同的是全部走es获取conversation_ids
    :param user_ids: LIST[USER_ID]
    :param offset: INT 偏移量
    :param size: INT 每页数量
    :param order_by: 排序规则
    :param last_reply_time_start: str 最后回复开始时间筛选
    :param last_reply_time_end: str 最后回复结束时间筛选
    :param reply_status: bool 回复状态（新消息、旧消息）
    :param is_star: bool
    :param user_id: int 精确搜索用户ID
    :param user_last_name: int 搜索用户昵称
    :param comment: int 搜索备注
    :return:
    """
    if not isinstance(user_ids, list):
        raise RPCPermanentError
    if not isinstance(size, int):
        raise RPCPermanentError
    if size <= 0 or size >= 50:
        size = 50
    es_filters = {'user_ids': user_ids}
    if is_star is not None and isinstance(is_star, bool):
        es_filters['is_star'] = is_star
    if last_reply_time_start is not None:
        es_filters['last_reply_time_start_gte'] = parser.parse('{}+0800'.format(last_reply_time_start)).isoformat()
    if last_reply_time_end is not None:
        es_filters['last_reply_time_end_lte'] = parser.parse('{}+0800'.format(last_reply_time_end)).isoformat()
    es_query = dict()
    # if search_content is not None:
    #     es_query = {
    #         'comment': search_content,
    #         'user_last_name': search_content,
    #     }
    if user_id is not None:
        es_query['user_id'] = user_id
    if user_last_name:
        es_query['user_last_name'] = user_last_name
    if comment:
        es_query['comment'] = comment
    es_sort_type = order_by
    # 全部
    es_result_total = search_conversation_from_es(offset=offset, size=size, filters=es_filters,
                                              query=es_query, sort_type=es_sort_type)
    # 已回复
    es_filters['multi_filter_status'] = {
        'status': True,
        'user_ids': user_ids,
    }
    es_result_reply = search_conversation_from_es(offset=offset, size=size, filters=es_filters,
                                 query=es_query, sort_type=es_sort_type)
    # 未回复
    es_filters['multi_filter_status'] = {
        'status': False,
        'user_ids': user_ids,
    }
    es_result_not_reply = search_conversation_from_es(offset=offset, size=size, filters=es_filters,
                                      query=es_query, sort_type=es_sort_type)
    # es_result = search_conversation_from_es(offset=offset, size=size, filters=es_filters,
    #                                         query=es_query, sort_type=es_sort_type)
    if reply_status == None:
        es_result = es_result_total
    else:
        if reply_status:
            es_result = es_result_reply
        else:
            es_result = es_result_not_reply
    _conversation_ids = es_result['conversation_ids']
    cus_ids = []
    for conversation_id in _conversation_ids:
        sub_ids = ConversationUserStatus.objects.filter(
            user_id__in=user_ids, conversation_id=conversation_id
        ).values_list('id', flat=True)
        cus_ids.extend(list(sub_ids))
    conversation_user_status = ConversationUserStatus.objects.filter(id__in=cus_ids).order_by('-last_reply_time')

    conversation_info_list = [cs.conversation.conversation_info_v3(cs, user_ids) for cs in conversation_user_status]
    conversation_id_to_user_id = {cs.conversation_id: cs.user_id for cs in conversation_user_status}
    for c in conversation_info_list:
        default = 1 if c['is_new'] else 0
        c['unread_num'] = UserUnread(conversation_id_to_user_id[c['id']]
                                     ).get_conversation_unread(c['id'], default=default)
    return {
        'conversation_list': conversation_info_list,
        'total_count': es_result_total['total_count'],
        'reply_total': es_result_reply['total_count'],
        'not_reply_total': es_result_not_reply['total_count']
    }


class Command(BaseCommand):

    DOCTOR_BUSINESS_CHANNAL_ID_ONLINE = 35

    # only check merchant id can use
    availableMerchantIDList = []

    # check merchant id and coupon can use
    availableMerchantIDListWithCoupon = []

    onlineTestuid = 33703995

    # content = [["area", "merchant_name", 6477328345687146383, 533, 0, "福建最大的整形机构在线独家补贴，领取红包为美减压，爱美就到爱美尔"]]

    c = [
        ["华东", "杭州珈禾医疗美容医院", 6433496798190426143, 59460, 60239, "杭州珈禾感谢您关注本院变美项目，送您一个400元红包可叠加平台红包共享优惠，有想咨询了解的请随时联系！"],
        ["华西", "重庆当代整形美容医院", 6328834449660238121, 54358, 54356, "与时尚接轨、与潮流同步，变美从重庆当代开始，期待您的咨询！"],
        ["华西", "重庆联合丽格美容医院", 6328834429254943862, 58448, 58449, "号外号外号外，重庆联合丽格8月优惠，红包多多，活动多多，快行动起来吧"],
        ["华西", "昆明艺星医疗美容医院", 6328834427111659985, 54300, 52967, "订制属于您专属的美丽，昆明艺星随时欢迎您的来访"],
        ["华西", "成都中医大银海医美", 6456090571630042287, 53015, 52170, "您有一份红包还没领取哟！这里是国家级三级医院，成都中医药大学附属医院银海眼科医院。关于变美方面小姐姐有任何问题都可以私信我哟！期待您的回复！"],
        ["华西", "四川娇点医学美容医院", 6328834489829137966, 60808, 0, "您的美丽，我来守候，期待您的咨询与到访。"],
        ["华西", "成都棕南医院", 6400946260789962410, 60683, 60682, "丰富的技术沉淀、专业的医美服务团队与雄厚的硬件基础，为每一位用户提供贴心、私密、个性化的美丽蜕变方案"],
        ["华西", "成都武侯格莱丽医疗美容门诊部", 6418755372676294081, 60706, 60705, "亲亲，您终于来啦，我们有国际化的医美技术、追求卓越的艺术审美、无微不至的人文服务，有什么问题随时来咨询我们哦。"],
        ["华西", "西安壹加壹医疗美容医院（西北旗舰店）", 6497039796123247593, 60822, 49072, "以”健康塑美，德行天下”为企业使命。医院集多种科室于一体，西安壹加壹是西北地区专业医美领航机构，欢迎您咨询，我们24小时在线为您服务。本月我们医院暑期特惠活动很优惠的"],
        ["华西", "西安现代医美中心", 6328834635807602879, 60802, 31205, "亲亲，看您有浏览我们项目，我们已经恭候多时了，领取的红包可以直接抵扣项目费用哦，有什么能帮您？"],
        ["华西", "重庆新瑞俪医疗美容", 6328834488243667252, 60029, 56648, "亲爱的小主，欢迎来到重庆新瑞俪，看您有关注我院的项目，小主是想了解哪方面呢？有什么疑虑也可以提出来，平台用户还有专享红包，请记得领取哦"],
        ["华西", "重庆珂琳雅医疗美容门诊部", 6328834459202328430, 60803, 60729, "抓住暑期的尾巴，活动不停，抓紧变美吧"],
        ["华西", "昆明美伊莱医疗美容", 6328834616790646964, 43295, 0, "终于等到你，还好我没放弃，小仙女，有什么需要了解的项目吗，昆明美伊莱暑期活动，项目大放价，随时欢迎咨询哦！"],
        ["华西", "四川省人民医院医疗集团友谊医院", 6382427920501107262, 60330, 60341, "国内轮廓品牌机构平台独家补贴， 领取红包为美减压吧！"],
        ["华西", "西安画美医疗美容医院", 6436029762384264000, 39243, 41214, "西北最大整形医院在线独家补贴，即刻领取20红包，更有多重折扣，欢迎在线询问！"],
        ["华中", "武汉五洲整形美容医院", 6329571025797364148, 60793, 0, "宝宝您好，感谢关注五洲整形，送您一张无门槛优惠券，有任何不明白的可以随时联系我们哦！"],
        ["华中", "武汉中翰整形外科医院", 6424920729401199852, 60792, 60794, "您好，中翰医学美容，看您有浏览我们医院的项目，亲亲是想了解哪方面呢？有什么疑虑也可以提出来，平台用户还有专享红包，请记得领取哦"],
        ["华中", "武汉韩辰医疗美容门诊", 6328834439799444957, 60804, 60805, "您好，韩辰医学美容，看您有浏览我们医院的项目，亲亲是想了解哪方面呢？有什么疑虑也可以提出来，平台用户还有专享红包，请记得领取哦"],
        ["华中", "武汉诠美医疗美容门诊部", 6328834462117380177, 60830, 60828, "您好，武汉诠美在炎炎夏日给您发福利啦。1.十余年本地口碑机构放心变美2.私信领尾款红包下单更优惠3.外地顾客报销路费4.预约到院即有专家面诊"],
        ["华中", "武汉奥黛丽医疗美容", 6329570573982637925, 60821, 0, "奥黛丽整形医院（武汉总院）#盛夏活动庆典#，①两人同行任意消费赠送水光针，②主动私信领取皮肤管理项目，有任何疑问可以私信了解哦~"]
    ]

    def handle(self, *args, **options):
        self.checkMerchant()
        self.checkCoupon()

        self.sendCoupon()

    def sendCoupon(self):

        resMerchantFailedSend = {}
        resMerchantSucceedSend = {}
        resConversationMap = {}

        sendReqNum = 0
        timeStart = time.time()

        for line in self.availableMerchantIDListWithCoupon:

            failedSendUserList = []
            succeedSendUserList = []
            allConversationID = []

            doctorIDList = []
            doctorUIDList = []
            sendCouponAdminUID = 0
            targetUserSet = set()
            sendCouponList = []
            conversationList = []

            merchantID = line[2]

            print()
            print()
            print("start send coupon of merchant id: {merchantID}".format(merchantID=merchantID))
            print("merchant id: ", merchantID)
            couponID1 = line[3]
            print("coupon id 1: ", couponID1)
            couponID2 = line[4]
            print("coupon id 2: ", couponID2)
            sendCouponList.append(couponID1)
            sendCouponList.append(couponID2)

            sendGiftList = self.getGiftID(sendCouponList)
            print "gift list: "
            print sendGiftList
            msgContent = line[5]
            print("msg content: ", msgContent)

            # get merchant info
            merchant = Merchant.objects.filter(id=merchantID).first()
            if not merchant:
                continue

            # get admin doctor id
            adminDoctorID = merchant.doctor.id

            # add admin doctor id to doctorIDList
            doctorIDList.append(adminDoctorID)

            # get other doctors
            doctors = MerchantRelevance.objects.filter(merchant_id=merchantID, doctor__doctor_type=DOCTOR_TYPE.DOCTOR)
            doctorCount = doctors.count()
            ds = doctors[0: doctorCount]
            otherDoctorList = [d.doctor.id for d in ds]

            # add other doctor id to doctorIDList
            doctorIDList.extend(otherDoctorList)

            # get all doctor info
            doctors = Doctor.objects.filter(pk__in=doctorIDList)

            for doctor in doctors:

                ddid = doctor.id
                duid = doctor.user_id

                # add every doctor uid to doctorUIDList
                doctorUIDList.append(duid)
                if ddid == adminDoctorID:
                    sendCouponAdminUID = duid

            # get message target user' user_id list at 2020/4/1 - 2020/7/31
            offsetNumber = 0
            while True:

                # get conversations between 2020/4/1 -- 2020/6/30 of merchant
                conversationResList = get_conversations_v3(
                    user_ids=doctorUIDList,
                    offset=offsetNumber,
                    size=50,
                    is_star=0,
                    last_reply_time_start="2020-01-01T00:00:00",
                    last_reply_time_end="2020-03-01T00:00:00",
                )

                # print("msg res: ")
                # pprint.pprint(conversationResList)
                resCount = conversationResList["total_count"]

                # no conversation
                if resCount <= 0:
                    break

                conversationListOne = conversationResList["conversation_list"]

                conversationList.extend(conversationListOne)

                if len(conversationListOne) < 50:
                    break

                offsetNumber += 50

            conversationNum = len(conversationList)
            print("conversation number of merchant: {merchantID} in 2020-1-1 and 2020-3-31 is ".format(
                merchantID=merchantID), conversationNum)

            # no conversation, handle next merchant
            if conversationNum == 0:
                continue

            # get target user id set
            # 因为发送者和接收者，顺序不定，所以都取出来去判断
            for conversationRow in conversationList:

                targetUserID0 = conversationRow["user_ids"][0]
                targetUserID1 = conversationRow["user_ids"][1]
                conversationID = conversationRow["id"]

                allConversationID.append(conversationID)

                if targetUserID0 not in doctorUIDList:
                    targetUserSet.add(targetUserID0)

                if targetUserID1 not in doctorUIDList:
                    targetUserSet.add(targetUserID1)

            # print("target user id set: ", targetUserSet)
            targetUserNum = len(targetUserSet)
            print("target user number of merchant id:{merchantID} is ".format(merchantID=merchantID), targetUserNum)

            targetUserSet.add(self.onlineTestuid)

            for targetUserOne in targetUserSet:

                for giftID in sendGiftList:

                    resSendCoupon = internal_message_send(
                        sender_user_id=sendCouponAdminUID,
                        target_user_id=targetUserOne,
                        msg_type=MESSAGE_TYPE.GIFT,
                        conversation_type=CONVERSATION_TYPE.MESSAGE,
                        content={"gift_id": giftID, "channel_id": self.DOCTOR_BUSINESS_CHANNAL_ID_ONLINE}
                    )

                    sendReqNum += 1

                    errSendGift = resSendCoupon["error"]
                    # send failed
                    if errSendGift == CODES.MESSAGE_CONTENT_FILTERED_OUT:
                        # print(
                        #     "Failed to send merchant:{merchantID}'s coupon: {couponGiftID} to user: {targetIDOne}".format(
                        #         merchantID=merchantID, couponGiftID=giftID, targetIDOne=targetUserOne))

                        failedGiftInfo = str(giftID)+"_"+str(targetUserOne)
                        failedSendUserList.append(failedGiftInfo)

                    # send success
                    # if errSendGift == CODES.SUCCESS:
                    #     print(
                    #         "Succeed to send merchant:{merchantID}'s coupon: {couponGiftID} to user: {targetIDOne}".format(
                    #             merchantID=merchantID, couponGiftID=giftID, targetIDOne=targetUserOne))

                # send msg
                resSendMsg = internal_message_send(
                    sender_user_id=sendCouponAdminUID,
                    target_user_id=targetUserOne,
                    msg_type=MESSAGE_TYPE.TEXT,
                    conversation_type=CONVERSATION_TYPE.MESSAGE,
                    content={"text": msgContent}
                )

                sendReqNum += 1

                errSendMsg = resSendMsg["error"]
                # if errSendMsg == CODES.MESSAGE_CONTENT_FILTERED_OUT:
                #     print(
                #         "Failed to send merchant:{merchantID}'s msg to user: {targetIDOne}".format(
                #             merchantID=merchantID, targetIDOne=targetUserOne))

                if errSendMsg == CODES.SUCCESS:
                    # print(
                    #     "Succeed to send merchant:{merchantID}'s msg to user: {targetIDOne}".format(
                    #         merchantID=merchantID, targetIDOne=targetUserOne))
                    succeedSendUserList.append(targetUserOne)

            resMerchantFailedSend[merchantID] = failedSendUserList
            resConversationMap[merchantID] = allConversationID
            resMerchantSucceedSend[merchantID] = succeedSendUserList


            print("send coupon complete of merchant: {merchantID}".format(merchantID=merchantID))

        print("res failed to send: ")
        print(resMerchantFailedSend)

        print("res succeed to send: ")
        print(resMerchantSucceedSend)

        print("conversation id list: ")
        print(resConversationMap)

        print("total send request number: ", sendReqNum)

        timeEnd = time.time()
        timeUse = timeEnd - timeStart
        print("time use: ", timeUse)

    def checkMerchant(self):

        unavailableMerchantList = []

        print "===== start to check merchant id ====="

        for line in self.c:
            merchantID = line[2]

            m = Merchant.objects.filter(id=merchantID).first()
            if not m:
                unavailableMerchantList.append(line)
            else:
                self.availableMerchantIDList.append(line)

        print "=== result of check merchant id ==="
        print "num of unavailable line with merchant:"
        print len(unavailableMerchantList)
        print "content of unavailable line with merchant:"
        print unavailableMerchantList
        print "===== end to check merchant id ====="

    def checkCoupon(self):

        unavailableMerchantInfoSet = set()

        print "===== start to check coupon id ====="

        for line in self.availableMerchantIDList:

            doctorIDList = []
            couponList = []

            merchantID = line[2]
            couponID1 = line[3]
            couponID2 = line[4]
            couponList.append(couponID1)
            couponList.append(couponID2)

            # get merchant obj
            m = Merchant.objects.filter(id=merchantID).first()

            # get admin doctor
            adminDoctorID = m.doctor.id
            print "admin doctor", adminDoctorID

            # add admin doctor id to doctorIDList
            doctorIDList.append(adminDoctorID)

            # get other doctors
            doctors = MerchantRelevance.objects.filter(merchant_id=merchantID, doctor__doctor_type=DOCTOR_TYPE.DOCTOR)
            doctorCount = doctors.count()
            ds = doctors[0: doctorCount]
            otherDoctorList = [d.doctor.id for d in ds]

            doctorIDList.extend(otherDoctorList)
            print "doctor list: ", doctorIDList

            # get doctor of every coupon, find it is exist in doctor list
            for couponID in couponList:
                if couponID == 0:
                    continue

                c = Coupon.objects.filter(id=couponID).first()
                if not c:
                    unavailableMerchantInfoSet.add(merchantID)
                    continue

                createDoctor = c.doctor
                if not createDoctor:
                    unavailableMerchantInfoSet.add(merchantID)
                    continue

                createDoctorID = createDoctor.id

                # coupon's create doctor is not belong to merchant,
                # add to unavailableMerchantInfoSet
                if createDoctorID not in doctorIDList:
                    unavailableMerchantInfoSet.add(merchantID)
                    continue

                couponType = c.coupon_type

                # coupon's type is not COUPON_TYPES.DOCTOR,
                # add to unavailableMerchantInfoSet
                if couponType != COUPON_TYPES.DOCTOR:
                    unavailableMerchantInfoSet.add(merchantID)
                    continue

                distributionStatus = c.distribution_status

                # coupon's distribution status is not COUPON_DISTRIBUTION_STATUS.OPEN,
                # add to unavailableMerchantInfoSet
                if distributionStatus != COUPON_DISTRIBUTION_STATUS.OPEN:
                    unavailableMerchantInfoSet.add(merchantID)
                    continue

                timeType = c.time_type

                # if time type is COUPON_TIME_TYPE.START_END,
                # check start_time <= now <= end_time,
                # if incompatible, add to unavailableMerchantInfoSet
                if timeType == COUPON_TIME_TYPE.START_END:
                    startDataTime = c.start_time
                    endDataTime = c.end_time

                    nowTime = datetime.datetime.now()

                    if nowTime < startDataTime or nowTime > endDataTime:
                        unavailableMerchantInfoSet.add(merchantID)
                        continue

                # if can't find GiftToCoupon obj where coupon.id=couponID,
                # add to unavailableMerchantInfoSet
                couponGift = GiftToCoupon.objects.filter(coupon_id=couponID).first()
                if not couponGift:
                    unavailableMerchantInfoSet.add(merchantID)
                    continue

                # if coupon is not enable, add to unavailableMerchantInfoSet
                isEnable = couponGift.coupon_enable
                if not isEnable:
                    unavailableMerchantInfoSet.add(merchantID)
                    continue

        print "===== result of check coupon id ====="
        print "num of unavailable line with merchant and coupon:"
        print len(unavailableMerchantInfoSet)
        print "content of unavailable line with merchant and coupon:"
        print unavailableMerchantInfoSet
        print "===== end to check coupon id ====="

        for line in self.c:

            mid = line[2]

            if mid in unavailableMerchantInfoSet:

                continue

            self.availableMerchantIDListWithCoupon.append(line)

        print "===== available line with merchant and coupon ====="
        print self.availableMerchantIDListWithCoupon
        print "================ END ======================"

    @staticmethod
    def getGiftID(couponList):

        giftList = []

        for couponID in couponList:
            if couponID == 0:
                continue

            couponGift = GiftToCoupon.objects.filter(coupon_id=couponID).first()
            giftID = couponGift.coupon_gift.id
            giftList.append(giftID)

        return giftList

