# -*- coding: utf-8 -*-

import logging

from django.conf import settings
from django.db import transaction
from django_curtail_uuid import CurtailUUID
from django_logit import logit
from django_response import response
from django_we.models import SubscribeUserInfo
from ipaddr import client_ip
from pywe_membercard import get_miniapp_extraData
from pywe_miniapp import get_session_info, get_session_key, get_userinfo, store_session_key
from pywe_storage import RedisStorage
from TimeConvert import TimeConvert as tc

from account.models import UserInfo, UserIntegralIncomeExpensesInfo
from mch.models import SaleclerkInfo
from statistic.models import RegisterStatisticInfo
from utils.error.errno_utils import ProductBrandStatusCode, UserStatusCode
from utils.redis.connect import r
from utils.redis.rprofile import set_profile_info


WECHAT = settings.WECHAT
logger = logging.getLogger('logit')


@logit
@transaction.atomic
def get_userinfo_api(request):
    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    appId = request.POST.get('appId', 'MINIAPP')

    if brand_id != settings.KODO_DEFAULT_BRAND_ID:
        return response(ProductBrandStatusCode.BRAND_NOT_MATCH)

    wxcfg = WECHAT.get(appId, {})

    appid = wxcfg.get('appID')
    secret = wxcfg.get('appsecret')

    code = request.POST.get('code', '')
    encryptedData = request.POST.get('encryptedData', '')
    iv = request.POST.get('iv', '')

    # {u'avatarUrl': u'http://wx.qlogo.cn/mmopen/vi_32/aSKcBBPpibyKNicHNTMM0qJVh8Kjgiak2AHWr8MHM4WgMEm7GFhsf8OYrySdbvAMvTsw3mo8ibKicsnfN5pRjl1p8HQ/0',
    #  u'city': u'Guangzhou',
    #  u'country': u'CN',
    #  u'gender': 1,
    #  u'language': u'zh_CN',
    #  u'nickName': u'Band',
    #  u'openId': u'oGZUI0egBJY1zhBYw2KhdUfwVJJE',
    #  u'province': u'Guangdong',
    #  u'unionId': u'ocMvos6NjeKLIBqg5Mr9QjxrP1FA',
    #  u'watermark': {u'appid': u'wx4f4bc4dec97d474b', u'timestamp': 1477314187}}
    session_key = get_session_key(appid=appid, secret=secret, code=code)
    # Get Userinfo
    userinfo = get_userinfo(appid=appid, secret=secret, code=code, session_key=session_key, encryptedData=encryptedData, iv=iv)

    # Get or Create User
    user, created = UserInfo.objects.select_for_update().get_or_create(unionid=userinfo.get('unionId', ''))

    # Set User_id
    if created:
        user.user_id = CurtailUUID.uuid(UserInfo, 'user_id')
        # 注册用户统计
        rsi, _ = RegisterStatisticInfo.objects.select_for_update().get_or_create(
            brand_id=brand_id,
            ymd=int(tc.local_string(format='%Y%m%d')),
        )
        rsi.num += 1
        rsi.save()

    # Set User Key's Value
    user.user_from = UserInfo.MINIAPP_USER
    user.appid = appId
    user.unionid = userinfo.get('unionId', '')
    user.openid_miniapp = userinfo.get('openId', '')
    user.sex = userinfo.get('gender', '')
    user.nickname = userinfo.get('nickName', '')
    user.avatar = userinfo.get('avatarUrl', '')
    user.country = userinfo.get('country', '')
    user.province = userinfo.get('province', '')
    user.city = userinfo.get('city', '')
    user.user_status = UserInfo.ACTIVATED
    user.signup_ip = client_ip(request)
    user.signup_at = tc.utc_datetime()

    try:
        subscribe = SubscribeUserInfo.objects.get(unionid=userinfo.get('unionId', ''), status=True)
    except SubscribeUserInfo.DoesNotExist:
        subscribe = None
    if subscribe:
        user.openid = subscribe.openid
        user.subscribe = True
    user.save()

    # Store Userinfo
    set_profile_info(user)

    # Store SessionKey
    store_session_key(appid=appid, secret=secret, session_key=session_key, unid=user.user_id, storage=RedisStorage(r))
    # Just for compatible because of store session_key has changed
    store_session_key(appid=appid, secret=secret, session_key=session_key, unid='', storage=RedisStorage(r))

    return response(200, 'Mini App Login Success', u'微信小程序登录成功', user.brandata(brand_id=brand_id))


@logit(res=True)
@transaction.atomic
def mini_login_api(request):
    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    appId = request.POST.get('appId', 'MINIAPP')

    if brand_id != settings.KODO_DEFAULT_BRAND_ID:
        return response(ProductBrandStatusCode.BRAND_NOT_MATCH)

    wxcfg = WECHAT.get(appId, {})

    appid = wxcfg.get('appID')
    secret = wxcfg.get('appsecret')

    code = request.POST.get('code', '')

    # // 正常返回的JSON数据包
    # {
    #     "openid": "OPENID",
    #     "session_key": "SESSIONKEY",
    # }
    #
    # // 满足UnionID返回条件时,返回的JSON数据包
    # {
    #     "openid": "OPENID",
    #     "session_key": "SESSIONKEY",
    #     "unionid": "UNIONID"
    # }
    # // 错误时返回JSON数据包(示例为Code无效)
    # {
    #     "errcode": 40029,
    #     "errmsg": "invalid code"
    # }
    session_info = get_session_info(appid=appid, secret=secret, code=code)
    logger.debug(session_info)
    session_key = session_info.get('session_key', '')
    unionid = session_info.get('unionid', '')
    openid = session_info.get('openid', '')

    # Get or Create User
    user, created = UserInfo.objects.select_for_update().get_or_create(openid_miniapp=openid)

    # Set User_id
    if created:
        user.user_id = CurtailUUID.uuid(UserInfo, 'user_id')
        # 注册用户统计
        rsi, _ = RegisterStatisticInfo.objects.select_for_update().get_or_create(
            brand_id=brand_id,
            ymd=int(tc.local_string(format='%Y%m%d')),
        )
        rsi.num += 1
        rsi.save()

    # Set User Key's Value
    user.user_from = UserInfo.MINIAPP_USER
    user.appid = appId
    if unionid:
        user.unionid = unionid
        try:
            subscribe = SubscribeUserInfo.objects.get(unionid=unionid, status=True)
        except SubscribeUserInfo.DoesNotExist:
            subscribe = None
        if subscribe:
            user.openid = subscribe.openid
            user.subscribe = subscribe.subscribe

    # 同步销售员手机号
    try:
        saleclerk = SaleclerkInfo.objects.get(unionid=user.unionid, is_auth=True, status=True)
    except SaleclerkInfo.DoesNotExist:
        saleclerk = None
    except SaleclerkInfo.MultipleObjectsReturned:
        saleclerk = None

    if saleclerk:
        user.phone = saleclerk.clerk_phone
        saleclerk.user_id = user.user_id
        saleclerk.save()
    user.user_status = UserInfo.ACTIVATED
    user.signup_ip = client_ip(request)
    user.signup_at = tc.utc_datetime()
    user.save()

    # Store Userinfo
    set_profile_info(user)

    # Store SessionKey
    store_session_key(appid=appid, secret=secret, session_key=session_key, unid=user.user_id, storage=RedisStorage(r))
    # Just for compatible because of store session_key has changed
    store_session_key(appid=appid, secret=secret, session_key=session_key, unid='', storage=RedisStorage(r))

    return response(200, 'Mini App Login Success', u'微信小程序登录成功', user.brandata(brand_id=brand_id))


@logit
@transaction.atomic
def get_userinfo_api2(request):
    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    user_id = request.POST.get('user_id', '')
    appId = request.POST.get('appId', 'MINIAPP')

    if brand_id != settings.KODO_DEFAULT_BRAND_ID:
        return response(ProductBrandStatusCode.BRAND_NOT_MATCH)

    wxcfg = WECHAT.get(appId, {})

    appid = wxcfg.get('appID')
    secret = wxcfg.get('appsecret')

    encryptedData = request.POST.get('encryptedData', '')
    iv = request.POST.get('iv', '')

    try:
        user = UserInfo.objects.select_for_update().get(user_id=user_id, status=True)
    except UserInfo.DoesNotExist:
        return response(UserStatusCode.USER_NOT_FOUND)

    # {u'avatarUrl': u'http://wx.qlogo.cn/mmopen/vi_32/aSKcBBPpibyKNicHNTMM0qJVh8Kjgiak2AHWr8MHM4WgMEm7GFhsf8OYrySdbvAMvTsw3mo8ibKicsnfN5pRjl1p8HQ/0',
    #  u'city': u'Guangzhou',
    #  u'country': u'CN',
    #  u'gender': 1,
    #  u'language': u'zh_CN',
    #  u'nickName': u'Band',
    #  u'openId': u'oGZUI0egBJY1zhBYw2KhdUfwVJJE',
    #  u'province': u'Guangdong',
    #  u'unionId': u'ocMvos6NjeKLIBqg5Mr9QjxrP1FA',
    #  u'watermark': {u'appid': u'wx4f4bc4dec97d474b', u'timestamp': 1477314187}}
    session_key = get_session_key(appid=appid, secret=secret, unid=user_id, storage=RedisStorage(r))
    # Get Userinfo
    userinfo = get_userinfo(appid=appid, secret=secret, session_key=session_key, encryptedData=encryptedData, iv=iv)

    # Set User Key's Value
    user.appid = appId
    user.unionid = userinfo.get('unionId', '')
    user.openid_miniapp = userinfo.get('openId', '')
    user.sex = userinfo.get('gender', '')
    user.nickname = userinfo.get('nickName', '')
    user.avatar = userinfo.get('avatarUrl', '')
    user.country = userinfo.get('country', '')
    user.province = userinfo.get('province', '')
    user.city = userinfo.get('city', '')
    try:
        subscribe = SubscribeUserInfo.objects.get(unionid=userinfo.get('unionId', ''), status=True)
    except SubscribeUserInfo.DoesNotExist:
        subscribe = None
    if subscribe:
        user.openid = subscribe.openid
        user.subscribe = subscribe.subscribe
    user.save()

    # Store Userinfo
    set_profile_info(user)

    return response(200, 'Mini App Get Userinfo Success', u'微信小程序获取用户信息成功', user.brandata(brand_id=brand_id))


@logit(res=True)
@transaction.atomic
def membercard_extradata(request):
    wxcfg = WECHAT.get('JSAPI', {})

    appid = wxcfg.get('appID')
    secret = wxcfg.get('appsecret')

    extraData = get_miniapp_extraData(settings.MEMBER_CARD_ID_TAMRON, outer_str='miniapp', appid=appid, secret=secret, storage=RedisStorage(r))

    return response(200, 'Get extraData Success', u'获取 extraData 成功', {
        'encrypt_card_id': extraData.get('encrypt_card_id', ''),
        'outer_str': extraData.get('outer_str', ''),
        'biz': extraData.get('biz', ''),
    })


@logit
@transaction.atomic
def user_integral_add(request):
    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    user_id = request.POST.get('user_id', '')
    integral = int(request.POST.get('integral', 0))
    remark = request.POST.get('remark')

    if brand_id != settings.KODO_DEFAULT_BRAND_ID:
        return response(ProductBrandStatusCode.BRAND_NOT_MATCH)

    try:
        user = UserInfo.objects.get(user_id=user_id, status=True)
    except UserInfo.DoesNotExist:
        return response(UserStatusCode.USER_NOT_FOUND)

    UserIntegralIncomeExpensesInfo.objects.create(
        brand_id=brand_id,
        user_id=user_id,
        integral_from=UserIntegralIncomeExpensesInfo.CONTRIBUTE,
        integral=integral,
        remark=remark
    )

    user.integral += integral
    user.save()

    return response(200, 'Add User Integral Success', u'添加用户投稿积分成功')