# coding=utf-8

import json
import time
from datetime import datetime

from django.conf import settings
from django.db.models import Q
from django.utils import timezone
from gm_types.gaia import (
    SERVICE_DISPLAY_PORT, SLIDE_USER_TYPE, SLIDE_PAYMENT_TYPE,
    WORLD_AREA_TYPE, SLIDE_TYPE, SERVICE_HOME_OPERATION,
    SERVICE_EVENT_TYPE, SOURCE_POSITION_DEVICE_TYPE, PLATFORM_CHOICES)

from api.manager.service_info_manager import service_feed_infos_by_special
from api.models import (
    ServiceHomeOperation,
    NewCategory, ServiceHomeBackground,
    Special,
    ServiceRelatedOperation,
    ChannelGift, ChannelGiftUserRelation)
from api.tool.datetime_tool import get_timestamp
from api.tool.user_tool import get_user_and_payment_info, get_user_from_context, is_new_service_user, \
    is_new_user_service_home, new_get_user_and_payment_info
from api.tool.city_tool import is_oversea
from api.tool.geo_tool import get_city_by_id
from launch.models import ServiceConfigureRelevant

from rpc.decorators import bind_context
from api.tool.get_query import get_query_by_usertype_and_location
from rpc.tool.log_tool import logging_exception


@bind_context('api/service_home/background')
def get_background(ctx):
    now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    base_query = Q(is_online=True, start_time__lte=now, end_time__gte=now)

    query = base_query
    background = ServiceHomeBackground.objects.filter(query).order_by('-id')
    result = {}
    if background.exists():
        background = background.first()
        result = {
            "background_img": background.background_img,
            "font_color": background.font_color,
        }
    return result


@bind_context('api/service_home/new_category')
def get_new_category(ctx, platform=None, device_id=None, city_id=None):
    user = get_user_from_context(ctx)
    query = get_query_by_usertype_and_location(user, platform=platform, device_id=device_id, city_id=city_id)

    new_category_qs = NewCategory.objects.filter(query).order_by('ordering', '-id').distinct()
    result = []
    for category in new_category_qs[:20]:
        data = {
            'id': category.id,
            'name': category.name,
            'icon_img': category.icon,
            'order': category.ordering,
            'tags': list(category.tags.values_list('id', flat=True)),
            'new_tags': list(category.new_tags.values_list('id', flat=True)),
        }
        result.append(data)
    return result


@bind_context('api/service_home/operational_location')
def get_operational_location(ctx, platform=None, device_id=None, city_id=None, display=SERVICE_DISPLAY_PORT.APP):
    now = datetime.now()
    base_query = Q(servicehome__is_online=True, servicehome__start_time__lte=now, servicehome__end_time__gte=now, servicehome__operation_type=SERVICE_HOME_OPERATION.ARRANGE)

    user = get_user_from_context(ctx)
    user_info = new_get_user_and_payment_info(user, platform, device_id)
    ### 获取新老用户信息
    user_type_choices = [SLIDE_USER_TYPE.ALL_USER]
    user_type_choices.append(SLIDE_USER_TYPE.NEW_USER if user_info.get('is_new_user') else SLIDE_USER_TYPE.OLD_USER)
    ## 获取是否支付信息
    payment_choices = [SLIDE_PAYMENT_TYPE.ALL_PAYMENT]
    payment_choices.append(SLIDE_PAYMENT_TYPE.HAVE_PAYMENT if user_info.get('have_payment') else SLIDE_PAYMENT_TYPE.NO_PAYMENT)

    user_query = Q(servicehome__user_type__in=user_type_choices) & Q(servicehome__payment_type__in=payment_choices)

    city_query = Q(servicehome__cities__isnull=True, servicehome__regions__isnull=True)
    if not city_id or city_id in WORLD_AREA_TYPE or is_oversea([city_id])[0]:
        pass
    else:
        city_query |= Q(servicehome__cities=city_id)
        region = None
        city = get_city_by_id(city_id)
        if city and city.province:
            try:
                region = city.province.region
            except:
                pass
        if region:
            city_query |= Q(servicehome__regions=region)
    """增加设备筛选"""
    if platform == PLATFORM_CHOICES.IPHONE:
        device_query = Q(servicehome__device_type__in=[SOURCE_POSITION_DEVICE_TYPE.ALL_DEVICE_TYPE, SOURCE_POSITION_DEVICE_TYPE.IOS_DEVICE])
    elif platform == PLATFORM_CHOICES.ANDROID:
        device_query = Q(servicehome__device_type__in=[SOURCE_POSITION_DEVICE_TYPE.ALL_DEVICE_TYPE, SOURCE_POSITION_DEVICE_TYPE.ANDROID])
    else:
        device_query = Q(servicehome__device_type=SOURCE_POSITION_DEVICE_TYPE.ALL_DEVICE_TYPE)
    display = 2 ** int(display)
    display_list = [i for i in range(2, 2 ** (1 + len(SERVICE_DISPLAY_PORT.choices))) if i % (display * 2) // display]
    port_query = Q(servicehome__display_port__in=display_list)
    query = base_query & user_query & city_query & port_query & device_query

    result = {}
    result['details'] = get_res_details(query)   #获取横排数据
    result['operation_type'] = SERVICE_HOME_OPERATION.ARRANGE
    if result['details'] == []:
        base_query_v2 = Q(servicehome__is_online=True, servicehome__start_time__lte=now, servicehome__end_time__gte=now,
                       servicehome__operation_type=SERVICE_HOME_OPERATION.SLIDE)
        query_v2 = base_query_v2 & user_query & city_query & port_query & device_query
        result['details'] = get_res_details(query_v2)  #若横排不存在,则取横滑
        result['operation_type'] = SERVICE_HOME_OPERATION.SLIDE
    return result

def get_res_details(query):
    show_positions = [1, 2, 3]
    res_details = []
    for sp in show_positions:
        pos_ope = ServiceRelatedOperation.objects.filter(position=sp).filter(query).order_by('-servicehome_id').first()
        if not pos_ope:
            continue
        p_detail = {}
        p_detail['position'] = pos_ope.position
        p_detail['img'] = pos_ope.image
        p_detail['id'] = pos_ope.id
        p_detail['jump_id'] = pos_ope.jump_id
        p_detail['banner_id'] = pos_ope.servicehome_id
        p_detail['operation_type'] = pos_ope.servicehome.operation_type
        p_detail['jump_type'] = pos_ope.jump_type
        try:
            if pos_ope.jump_type == SLIDE_TYPE.SPECIAL:
                p_detail['is_new_special'] = Special.objects.get(id=pos_ope.jump_id).is_new_special
        except:
            import traceback
            traceback.format_exc()
            pass
        res_details.append(p_detail)
    return res_details

@bind_context('api/service_home/flash_sale')
def get_flash_sale(ctx, city_id=None):
    # 美购首页限时抢购
    now = datetime.now()
    base_query = Q(start_time__lte=now, end_time__gte=now, event_type=SERVICE_EVENT_TYPE.FLASH_SALE)

    if not city_id or city_id in WORLD_AREA_TYPE or is_oversea([city_id])[0]:
        city_query = Q(servicehome_city__city__isnull=True)
        query = base_query & city_query
        ser_con = ServiceConfigureRelevant.objects.filter(query).order_by('-id').first()
    else:
        city_query = Q(servicehome_city__city_id=city_id)
        query = base_query & city_query
        ser_con = ServiceConfigureRelevant.objects.filter(query).order_by('-id').first()
        if not ser_con:
            city_query = Q(servicehome_city__city__isnull=True)
            query = base_query & city_query
            ser_con = ServiceConfigureRelevant.objects.filter(query).order_by('-id').first()

    if ser_con:
        result = {
            'id': ser_con.id,
            'special_id': ser_con.special_id,
            'title': ser_con.title,
            'start_time': str(ser_con.start_time),
            'end_time': str(ser_con.end_time),
            'start_timestamp': str(get_timestamp(ser_con.start_time)) if ser_con.start_time else '',
            'end_timestamp': str(get_timestamp(ser_con.start_time)) if ser_con.start_time else '',
            'now_timestamp': time.time(),
            'count_down' : (ser_con.end_time - timezone.now()).total_seconds()
        }
        services = service_feed_infos_by_special([ser_con.special_id])
        result['services'] = services[ser_con.special_id] if services else {}
    else:
        result = {}
    return result


@bind_context('api/service_home/find_goods')
def get_find_goods(ctx, city_id=None):
    # 美购首页新人必买/发现好货
    user = get_user_from_context(ctx)
    now = datetime.now()
    base_query = Q(start_time__lte=now, end_time__gte=now, event_type=SERVICE_EVENT_TYPE.NEW_OLD_USER)

    if not user:
        is_new_user = True
        is_new_coupons = False
    else:
        is_new_user = is_new_user_service_home(user)
        is_new_coupons = False
        channel_gift_ids = list(ChannelGift.objects.filter(gift_id=settings.SERVICE_HOME_NEW_USER_GIFT_ID).values_list('id', flat=True))
        if channel_gift_ids:
            for channel_gift_id in channel_gift_ids:
                if ChannelGiftUserRelation.objects.filter(channel_gift_id=channel_gift_id, user=user).exists():
                    is_new_coupons = True
                    break

    user_info = {
        'is_new_user': is_new_user,  ##是否新用户
        'is_new_coupons': is_new_coupons,  ## 是否已领新人红包
        'coupons_url': "",  ##新人红包url
        'icon_image': settings.NEW_USER_COUPON_ICON_IMAGE,  ### 新人红包图
    }
    user_type = SLIDE_USER_TYPE.NEW_USER if is_new_user else SLIDE_USER_TYPE.OLD_USER

    if not city_id or city_id in WORLD_AREA_TYPE or is_oversea([city_id])[0]:
        city_query = Q(servicehome_city__city__isnull=True)
        query = base_query & city_query & Q(user_type=user_type)
        ser_con = ServiceConfigureRelevant.objects.filter(query).order_by('-id').first()
    else:
        city_query = Q(servicehome_city__city_id=city_id)
        query = base_query & city_query & Q(user_type=user_type)
        ser_con = ServiceConfigureRelevant.objects.filter(query).order_by('-id').first()
        if not ser_con:
            city_query = Q(servicehome_city__city__isnull=True)
            query = base_query & city_query & Q(user_type=user_type)
            ser_con = ServiceConfigureRelevant.objects.filter(query).order_by('-id').first()

    if ser_con:
        result = {
            'id': ser_con.id,
            'special_id': ser_con.special_id,
            'title': ser_con.title,
        }
        services = service_feed_infos_by_special([ser_con.special_id])
        result['services'] = services[ser_con.special_id] if services else {}
        if is_new_user:
            result['user_info'] = user_info
    else:
        result = {}

    return result
