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

from __future__ import division

import json

import shortuuid
from curtail_uuid import CurtailUUID
from django.conf import settings
from django.core.serializers.json import DjangoJSONEncoder
from django_response import response
from logit import logit
from TimeConvert import TimeConvert as tc

from account.models import UserInfo
from group.models import GroupInfo, GroupUserInfo
from utils.admin_utils import have_active_group, is_group_admin, is_group_subadmin
from utils.error.errno_utils import GroupStatusCode, GroupUserStatusCode, TokenStatusCode, UserStatusCode
from utils.redis.connect import r
from utils.redis.rgroup import get_group_info, get_group_users_info, set_group_info, set_group_users_info
from utils.redis.rkeys import TOUR_GUIDE_GROUP_CUR_GATHER_INFO, TOUR_GUIDE_GROUP_CUR_SESSION
from utils.redis.rtourguide import get_tour_guide_own_group, set_tour_guide_own_group
from utils.redis.rtouruser import get_tour_user_belong_group
from utils.storage_qiniu_utils import file_save


@logit
def tg_group_create_api(request):
    """ 旅行团创建 """
    user_id = request.POST.get('user_id', '')
    group_name = request.POST.get('group_name', '')
    group_default_avatar = int(request.POST.get('group_default_avatar', 0))
    started_at = tc.utc_string_to_utc_datetime(request.POST.get('started_at', ''), format='%Y-%m-%dT%H:%M:%SZ')  # UTC, %Y-%m-%dT%H:%M:%SZ
    ended_at = tc.utc_string_to_utc_datetime(request.POST.get('ended_at', ''), format='%Y-%m-%dT%H:%M:%SZ')  # UTC, %Y-%m-%dT%H:%M:%SZ
    total_persons = int(request.POST.get('total_persons', 1))

    # 用户校验
    try:
        user = UserInfo.objects.get(user_id=user_id)
    except UserInfo.DoesNotExist:
        return response(UserStatusCode.USER_NOT_FOUND)

    # 权限校验
    if not user.istourguide:
        return response(GroupStatusCode.NOT_GROUP_ADMIN)

    # 旅行团校验
    if have_active_group(user_id):
        return response(GroupStatusCode.ONLY_ONE_ACTIVE_GROUP_ALLOWED)

    # 群组唯一标识
    group_id = CurtailUUID.uuid(GroupInfo, 'group_id')

    # 群组记录创建
    group = GroupInfo.objects.create(
        group_id=group_id,
        admin_id=user_id,
        group_name=group_name,
        group_default_avatar=group_default_avatar,
        group_from=GroupInfo.TOURGUIDE_GROUP,
        name=user.name,
        phone=user.phone,
        started_at=started_at,
        ended_at=ended_at,
        total_persons=total_persons,
    )

    # Redis 群组数据缓存
    group_info = set_group_info(group)

    # 群组用户记录创建
    GroupUserInfo.objects.create(
        group_id=group_id,
        user_id=user_id,
        nickname=user.final_nickname,
        avatar=user.avatar,
        admin=True,
        user_status=GroupUserInfo.PASSED,
        passed_at=tc.utc_datetime(),
        subadmin=True,
        name=user.name,
        phone=user.phone,
    )

    # Redis 群组用户数据缓存
    group_users = set_group_users_info(group)

    # Redis 设置导游拥有的旅行团
    set_tour_guide_own_group(user_id, group_id)

    return response(200, 'Create Tour Guide Group Success', u'旅行团创建成功', {
        'group_id': group_id,
        'group': group_info,
        'users': group_users,
    })


@logit
def tg_group_detail_api(request):
    """ 旅行团详情 """
    group_id = request.POST.get('group_id', '')
    user_id = request.POST.get('user_id', '')

    if not group_id:
        group_id = get_tour_guide_own_group(user_id)

    group_users_info = get_group_users_info(group_id, user_id)
    # Remove tourguide
    group_passed_users = [uinfo for uinfo in group_users_info['passed'] if not uinfo['subadmin']]
    # Update passed users
    group_users_info['passed'] = group_passed_users
    # Update passed count
    group_users_info['passed_count'] = len(group_passed_users)
    # Sum(relative_persons)
    group_users_info['relative_persons'] = sum([user['relative_persons'] for user in group_passed_users])

    return response(200, 'Get Tour Guide Group Detail Info Success', u'获取旅行团详情成功', {
        'group_id': group_id,
        'group': get_group_info(group_id),
        'users': group_users_info,
    })


@logit
def pai2_tginfo_api(request):
    """ 首页旅行团信息 """
    user_id = request.POST.get('user_id', '')

    # 获取用户当前所处旅行团
    group_id = get_tour_user_belong_group(user_id)
    if not group_id:
        return response(GroupUserStatusCode.USER_HAS_NOT_JOIN_GROUP)

    group_info = get_group_info(group_id)

    # Check whether ended
    ended_at = group_info.get('ended_at', '')
    if ended_at and tc.utc_datetime() > (tc.utc_string_to_utc_datetime(ended_at, format='%Y-%m-%dT%H:%M:%SZ') if isinstance(ended_at, basestring) else ended_at):
        return response(GroupStatusCode.GROUP_HAS_ENDED)

    # Check gather info
    gather_at = group_info.get('gather_at', '')
    if gather_at and tc.utc_datetime() > (tc.utc_string_to_utc_datetime(gather_at, format='%Y-%m-%dT%H:%M:%SZ') if isinstance(gather_at, basestring) else gather_at):
        group_info['gather_at'] = ''
        group_info['gather_lon'] = ''
        group_info['gather_lat'] = ''
        group_info['gather_location'] = ''

    return response(200, 'Get Tour Guide Group Detail Info Success', u'获取旅行团详情成功', {
        'group_id': group_id,
        'group': group_info,
        'users': get_group_users_info(group_id, user_id),
    })


@logit(body=settings.LOGIT_BODY_FLAG, res=settings.LOGIT_RES_FLAG)
def tg_group_update_api(request):
    """ 旅行团更新 """
    group_id = request.POST.get('group_id', '')
    admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')
    group_name = request.POST.get('group_name', '')
    group_desc = request.POST.get('group_desc', '')

    group_avatar = request.FILES.get('group_avatar', '')

    started_at = tc.utc_string_to_utc_datetime(request.POST.get('started_at', ''), format='%Y-%m-%dT%H:%M:%SZ')  # UTC, %Y-%m-%dT%H:%M:%SZ
    ended_at = tc.utc_string_to_utc_datetime(request.POST.get('ended_at', ''), format='%Y-%m-%dT%H:%M:%SZ')  # UTC, %Y-%m-%dT%H:%M:%SZ
    total_persons = int(request.POST.get('total_persons', 0))

    attentions = request.FILES.get('attentions', '')
    schedules = request.FILES.get('schedules', '')

    # 群组校验
    try:
        group = GroupInfo.objects.get(group_id=group_id)
    except GroupInfo.DoesNotExist:
        return response(GroupStatusCode.GROUP_NOT_FOUND)

    # 权限校验
    if group.admin_id != admin_id:
        return response(GroupStatusCode.NOT_GROUP_ADMIN)

    # 群组名称更新
    if group_name:
        group.group_name = group_name
    # 群组描述更新
    if group_desc:
        group.group_desc = group_desc
    # 群组头像更新
    if group_avatar:
        group.group_avatar = file_save(group_avatar, prefix='group', ext='.jpeg').photo_path
    # 起止时间更新
    if started_at:
        group.started_at = started_at
    if ended_at:
        group.ended_at = ended_at
    # 旅行团总人数更新
    if total_persons:
        group.total_persons = total_persons
    # 注意事项更新
    if attentions:
        group.attentions_path = file_save(attentions, prefix='tour', ext='.jpeg').photo_path
    # 行程安排更新
    if schedules:
        group.schedules_path = file_save(schedules, prefix='tour', ext='.jpeg').photo_path
    group.save()

    # Redis 群组数据缓存更新
    group_info = set_group_info(group)

    return response(200, 'Update Group Success', u'群组更新成功', {
        'group_id': group_id,
        'group': group_info,
        'users': get_group_users_info(group_id, admin_id),
    })


@logit
def tg_group_close_api(request):
    """ 旅行团关闭 """
    group_id = request.POST.get('group_id', '')
    admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')

    # 群组校验
    try:
        group = GroupInfo.objects.get(group_id=group_id)
    except GroupInfo.DoesNotExist:
        return response(GroupStatusCode.GROUP_NOT_FOUND)

    # 权限校验
    if group.admin_id != admin_id:
        return response(GroupStatusCode.NOT_GROUP_ADMIN)

    # 群组解锁
    group.group_closed = True
    group.closed_at = tc.utc_datetime()
    group.save()

    # Redis 群组数据缓存更新
    set_group_info(group)

    return response(200, 'Close Tour Guide Group Success', u'旅行团关闭成功')


@logit
def tg_group_gather_start_api(request):
    """ 旅行团设置集合时间和地点 """
    group_id = request.POST.get('group_id', '')
    admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')
    gather_at = tc.utc_string_to_utc_datetime(request.POST.get('gather_at', ''), format='%Y-%m-%dT%H:%M:%SZ')  # UTC, %Y-%m-%dT%H:%M:%SZ
    gather_lon = request.POST.get('lon', '')  # 经度
    gather_lat = request.POST.get('lat', '')  # 纬度
    gather_location = request.POST.get('gather_location', '')  # 地点
    gather_screenshot = request.FILES.get('gather_screenshot', '')

    # 群组校验
    try:
        group = GroupInfo.objects.get(group_id=group_id)
    except GroupInfo.DoesNotExist:
        return response(GroupStatusCode.GROUP_NOT_FOUND)

    # 权限校验
    if not is_group_subadmin(group_id, admin_id):
        return response(GroupStatusCode.NOT_GROUP_SUBADMIN)

    # 集合信息设置
    group.gather_at = gather_at
    group.gather_lon = gather_lon
    group.gather_lat = gather_lat
    group.gather_location = gather_location
    if gather_screenshot:
        group.gather_screenshot = file_save(gather_screenshot, prefix='tour', ext='.jpeg').photo_path
    group.save()

    # Redis 群组数据缓存更新
    set_group_info(group)

    # 更新Session
    r.pipeline().set(
        TOUR_GUIDE_GROUP_CUR_SESSION % group_id, shortuuid.uuid()
    ).set(
        TOUR_GUIDE_GROUP_CUR_GATHER_INFO % group_id, json.dumps({
            'gather_at': gather_at,
            'gather_lon': gather_lon,
            'gather_lat': gather_lat,
            'gather_location': gather_location,
        }, cls=DjangoJSONEncoder)
    ).execute()

    return response(200, 'Set Tour Guide Group Gather Info Success', u'设置旅行团集合信息成功')


@logit
def tg_group_token_api(request):
    """ 旅行团权限管理票据 """
    admin_id = request.POST.get('admin_id', '') or request.POST.get('user_id', '')

    # 旅行团校验
    if not have_active_group(admin_id):
        return response(GroupStatusCode.ACTIVE_GROUP_NOT_FOUND)

    # 获取旅行团唯一标识
    group_id = get_tour_guide_own_group(admin_id)

    return response(200, 'Generate Token Success', u'生成票据成功', {
        'token': r.token(group_id + admin_id, time=180)
    })


@logit
def tg_group_transfer_api(request):
    """ 旅行团权限管理转移 """
    admin_id = request.POST.get('admin_id', '')  # 导游唯一标识，识别二维码获取
    user_id = request.POST.get('user_id', '')
    token = request.POST.get('token', '')

    # 旅行团校验
    if have_active_group(user_id):
        return response(GroupStatusCode.ONLY_ONE_ACTIVE_GROUP_ALLOWED)

    # 获取旅行团唯一标识
    group_id = get_tour_guide_own_group(admin_id)

    # 票据校验
    if not r.token_exists(group_id + admin_id, token):
        return response(TokenStatusCode.TOKEN_NOT_FOUND)

    # 用户校验
    try:
        user = UserInfo.objects.get(user_id=user_id)
    except UserInfo.DoesNotExist:
        return response(UserStatusCode.USER_NOT_FOUND)

    # 群组校验
    try:
        group = GroupInfo.objects.get(group_id=group_id)
    except GroupInfo.DoesNotExist:
        return response(GroupStatusCode.GROUP_NOT_FOUND)

    # 权限校验
    if not is_group_admin(group_id, admin_id):
        return response(GroupStatusCode.NOT_GROUP_ADMIN)

    # 群组用户记录创建，若记录不存在，则创建，若记录已存在，则更新
    group_user, created = GroupUserInfo.objects.get_or_create(
        group_id=group_id,
        user_id=user_id,
        defaults={
            'nickname': user.final_nickname,
            'avatar': user.avatar,
            'user_status': GroupUserInfo.PASSED,
            'passed_at': tc.utc_datetime(),
            'subadmin': True,
            'name': user.name,
            'phone': user.phone,
        }
    )

    if not created:
        group_user.current_id = -1
        group_user.nickname = user.final_nickname
        group_user.avatar = user.avatar
        group_user.user_status = GroupUserInfo.PASSED
        group_user.passed_at = tc.utc_datetime()
        group_user.subadmin = True
        group_user.name = user.name
        group_user.phone = user.phone
        group_user.status = True
        group_user.save()

    # Redis 群组用户数据缓存
    group_users = set_group_users_info(group)

    # Redis 设置导游拥有的旅行团
    set_tour_guide_own_group(user_id, group_id)

    return response(200, 'Transfer Tour Guide Group Success', u'转移旅行团管理权成功', {
        'group_id': group_id,
        'group': group.data,
        'users': group_users,
    })
