# coding=utf-8
import json

from datetime import datetime

from django.db import IntegrityError
from django.db import transaction
from django.db.models import Q
from gm_types.gaia import GRAY_TYPE

from rpc.decorators import bind_context
from api.models.greetpopup import GreetingPopup
from api.tool.log_tool import logging_exception
from ..datatables import GreetingPopupDT
from rpc.exceptions import RPCNotFoundException, RPCIntegrityError
from rpc.tool.dict_mixin import to_dict
from rpc.tool.log_tool import info_logger
from ..queries.popup import PopupDQ


popup_pre = 'hera/popup'


@bind_context(popup_pre + '/query')
def popup_query(ctx, options):
    dqobj = PopupDQ()
    return dqobj.process(**options)


@bind_context(popup_pre + '/list')
def popup_datatable(request, req_data):
    dtobj = GreetingPopupDT(GreetingPopup)
    return dtobj.process(req_data)


@bind_context(popup_pre + '/listupdate')
def popup_listupdate(ctx, items):
    info = []
    for obj in items:
        popup = GreetingPopup.objects.get(pk=obj['key'])
        if popup.type == '0' and obj['is_online']:
            has_rank_ids = list(GreetingPopup.objects.filter(is_online=True, type='0', rank=popup.rank).
                                values_list('id', flat=True))
            if popup.id in has_rank_ids:
                has_rank_ids.remove(popup.id)
            if len(has_rank_ids):
                continue
        popup.is_online = obj['is_online']
        if obj.get('rank'):
            popup.rank = obj['rank']
        popup.save()
        info.append(obj['key'])
    return info


@bind_context(popup_pre + '/get')
def popup_detail(ctx, id, options=None):
    try:
        popup = GreetingPopup.objects.get(id=id)
    except:
        raise RPCNotFoundException
    if options is None:
        options = {
            'fields': None,
            'excludes': None,
            'expands': None,
        }
    data = to_dict(popup, **options)
    return data


@bind_context(popup_pre + '/edit')
def popup_edit(ctx, id=None, popup_info=None):
    if popup_info is None:
        return None

    popup_info['service_id'] = popup_info.pop('service')
    popup_info['tag_id'] = popup_info.pop('tag')
    popup_info['special_id'] = popup_info.pop('special')
    popup_info['aggregation_id'] = popup_info.pop('aggregation_id')
    popup_info['visualpage_id'] = popup_info.pop('visualpage_id')
    popup_info['deep_link'] = popup_info.pop('deep_link', False)

    gray_info = popup_info.pop('gray_value', [])
    popup_info['gray_value'] = ','.join(gray_info)
    popup_info['gray_type'] = popup_info.pop('gray_type', GRAY_TYPE.ALL)

    for key in ['diary_id', 'topic_id', 'activity_id', 'aggregation_id', 'visualpage_id']:
        popup_info[key] = popup_info.pop(key) or None

    if popup_info['type'] == '1' and popup_info['rank'] is None:
        popup_info['rank'] = 999999

    if popup_info['type'] == '0' and popup_info['is_online']:
        has_rank_ids = list(GreetingPopup.objects.filter(is_online=True, rank=popup_info['rank'], type='0').
                            values_list('id', flat=True))
        if id and int(id) in has_rank_ids:
            has_rank_ids.remove(int(id))
        if len(has_rank_ids):
            return {
                'error': 1,
                'id': id,
                'has_rank_ids': has_rank_ids,
            }

    if id is None:
        try:
            cities = popup_info.pop('cities')
            regions = popup_info.pop('regions')
            popup = GreetingPopup.objects.create(**popup_info)
            popup.cities = cities
            popup.regions = regions
        except IntegrityError:
            raise RPCIntegrityError
    else:
        try:
            popup = GreetingPopup.objects.get(id=id)
            if popup.type == '0' and popup.is_online:
                has_rank_ids = list(GreetingPopup.objects.filter(is_online=True, rank=popup_info['rank']).values_list('id', flat=True))
                if popup.id in has_rank_ids:
                    has_rank_ids.remove(popup.id)
                if len(has_rank_ids):
                    return {
                        'error': 1,
                        'id': None,
                        'has_rank_ids': has_rank_ids
                    }
            for k, v in popup_info.iteritems():
                setattr(popup, k, v)
            popup.save()
        except:
            info_logger.info(__import__('traceback').format_exc())
            raise RPCNotFoundException
    return {
        'error': 0,
        'id': popup.id,
        'conflict_ids': get_conflict_ids(popup),
    }


@bind_context(popup_pre + '/replication_popup')
def replication_popup(ctx, popup_id):
    """复制开屏"""
    g_obj = None
    greet_obj = GreetingPopup.objects.get(id=popup_id)
    old_data = to_dict(
        greet_obj,
        excludes=[
            'tag', 'service', 'special', 'regions', 'cities', 'id'
        ]
    )
    with transaction.atomic():
        try:
            g_obj = GreetingPopup.objects.create(**old_data)
            g_obj.service_id = greet_obj.service_id
            g_obj.special_id = greet_obj.special_id
            g_obj.tag_id = greet_obj.tag_id
            g_obj.regions = list(greet_obj.regions.values_list('id', flat=True))
            g_obj.cities = list(greet_obj.cities.values_list('id', flat=True))
            g_obj.save()
        except Exception as e:
            logging_exception()
            raise e

    return {'id': g_obj.id}


def get_conflict_ids(popup):
    if not (popup.type == '1' and popup.is_online):
        return []
    greeting_popup = GreetingPopup.objects.filter(is_online=True, type='1')\
        .exclude(is_sustain=popup.is_sustain)\
        .exclude(end_time__lt=datetime.now())\
        .exclude(start_time__gt=popup.end_time)\
        .exclude(end_time__lt=popup.start_time)
    return [x.id for x in greeting_popup]
