# coding=utf-8
from __future__ import absolute_import, print_function, unicode_literals

import datetime
import random

from celery import shared_task
from django.db.models import Q
from django.db import IntegrityError

from api.models import SUBSCRIBE_PLATFORM_IPHONE
from api.models import iPhone, Android, iOsDevice
from api.models import UserExtra, User, UserChangeLog

from statistic.models import Device
from statistic.utils.idfv_tool import add_idfv
from social.models import SocialInfo
from rpc.cache import sleep_user_cache


@shared_task
def set_city_by_lat_lng_or_cityname(user_id, lat, lng, cityname=None, current_city_id=None):
    from api.tool.user_tool import get_user_extra_by_user_id
    from api.tool.geo_tool import set_city_for_user

    user_extra = get_user_extra_by_user_id(user_id)

    # updated at v5.9.1
    # http://wiki.gengmei.cc/pages/viewpage.action?pageId=1050321
    # set user city by order current_city_id -> lng/lat -> cityname
    if not user_extra.city:
        # 用户的城市信息为空时添加 需求在4.7.1文档
        set_city_for_user(user_extra, city_id=current_city_id, city_name=cityname, lat=lat, lng=lng)

@shared_task
def follow_suozhang(user_id):
    social_info = SocialInfo(uid=user_id)
    social_info.follow(uid=22)  # yep, uid=22 is suozhang, period.


@shared_task
def record_device_info(user_id, device_id=None, platform=None, release=None, idfv=None,
                       version=None, os_version=None, model=None, screen=None, channel=None, **kwargs):
    # 判断所需数据是否完整
    if not device_id:
        return 'No device_id'

    if not platform:
        return 'No platform'

    try:
        device, created = add_idfv(Device, platform, device_id)
    except IntegrityError:
        return 'exists'

    if created:
        # 只有第一次创建的时候，才设置频道
        device.channel = channel
        device.created_time = datetime.datetime.now()
        # 设备创建时, 打印激活日志
        # ctx.logger.app(is_activation=True)

    device.version = version
    device.os_version = os_version
    device.model = model
    device.screen = screen
    # if platform.lower() == 'android' and not device.idfv:
    #     device.idfv = device_id

    from api.tool.user_tool import get_user_by_id
    user = get_user_by_id(user_id)
    if not user:
        return u'no user', created

    try:
        device.user.add(user)
        device.save()
        return 'new', created
    except IntegrityError:
        return 'exists', created


@shared_task
def update_device_pushinfo(
        platform, device_id, version, channel, os_version,
        model, screen, release, user_id, idfv=None, **kwargs):
    """
        在用户登录时将设备的信息保存到数据库中，以供push操作时使用
    """
    # TODO: 一、添加缺失的参数 idfv。二、考虑使用一个类包装这一堆参数。
    #       具体情况可以参考各个调用处（如 api/person/login）和相关的函数（如 record_device_info）。

    if (len(device_id) > 0) and (platform == SUBSCRIBE_PLATFORM_IPHONE):
        try:
            user = User.objects.get(pk=user_id)
            # 删除当前用户的其他设备信息，以及删除当前设备的其他用户信息
            iPhone.objects.filter(~Q(user=user), udid=device_id).delete()
            iPhone.objects.filter(~Q(udid=device_id), user=user).delete()

            iphone, _created = iPhone.objects.get_or_create(
                user=user, udid=device_id)
            iphone.is_dist = release == 1
            iphone.version = version
            iphone.save()
        except Exception:
            pass

        if (len(device_id) > 0) and (platform == SUBSCRIBE_PLATFORM_IPHONE):
            device, _created = iOsDevice.objects.get_or_create(udid=device_id)
            if not ((device.version == version) and (device.is_dist == (release == 1))):
                device.is_dist = release == 1
                device.version = version
                device.save()
        return platform, device_id

    elif platform.lower() == "android":
        try:
            user = User.objects.get(pk=user_id)
            android, _created = Android.objects.get_or_create(user=user)
            android.version = version
            android.save()
            return platform, device_id
        except Exception:
            pass


_MAX_SLEEP_PERSON = 5000


def get_sleep_user(repeat_times):
    user_extras = []

    index_seq = random.sample(xrange(_MAX_SLEEP_PERSON), repeat_times)

    for i in index_seq:
        try:
            extra = UserExtra.objects.get(id=sleep_user_cache.get('sleep_user_index:' + str(i)))
            user_extras.append(extra)
        except UserExtra.DoesNotExist:
            pass

    return user_extras


@shared_task
def create_sleep_user_to_redis():
    user_extras = UserExtra.objects.filter(last_login__lt=datetime.datetime(2015, 1, 1))
    count = user_extras.count()
    rand_start = random.randint(0, count-_MAX_SLEEP_PERSON)
    user_extras = user_extras[rand_start:rand_start + _MAX_SLEEP_PERSON]
    i = 0
    for user_extra in user_extras:
        sleep_user_cache.set('sleep_user_index:' + str(i), user_extra.id)
        i += 1


@shared_task
def record_user_change_log(user_id, change_type, operate_type, comment=''):
    obj = UserChangeLog(
        user_id=user_id,
        change_type=change_type,
        operate_type=operate_type,
        comment=comment
    )
    obj.save()
