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

from __future__ import division

import json
import os

import shortuuid
from curtail_uuid import CurtailUUID
from django.conf import settings
from django.core.files.storage import default_storage
from django.core.serializers.json import DjangoJSONEncoder
from logit import logit
from TimeConvert import TimeConvert as tc

from account.models import UserInfo
from group.models import GroupInfo, GroupUserInfo
from utils.error.errno_utils import GroupStatusCode, GroupUserStatusCode, TokenStatusCode, UserStatusCode
from utils.error.response_utils import response
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,
                               TOUR_GUIDE_GROUP_USER_BELONG)
from utils.redis.rtourguide import get_tour_guide_own_group, set_tour_guide_own_group


r = settings.REDIS_CACHE


@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', ''))  # UTC, %Y-%m-%dT%H:%M:%SZ
    ended_at = tc.utc_string_to_utc_datetime(request.POST.get('ended_at', ''))  # UTC, %Y-%m-%dT%H:%M:%SZ
    total_persons = request.POST.get('total_persons', '')

    # 用户校验
    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 GroupInfo.objects.filter(
        admin_id=user_id,
        group_closed=False,
        status=True,
        ended_at__gt=tc.utc_datetime(),
    ).exists():
        return response(GroupStatusCode.COULD_HAVE_ONLY_ONE_ACTIVE_GROUP)

    # 群组唯一标识
    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', '')

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


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

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

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


@logit
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', ''))  # UTC, %Y-%m-%dT%H:%M:%SZ
    ended_at = tc.utc_string_to_utc_datetime(request.POST.get('ended_at', ''))  # UTC, %Y-%m-%dT%H:%M:%SZ
    total_persons = request.POST.get('total_persons', '')

    # 群组校验
    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.NO_UPDATE_PERMISSION)

    # 群组名称更新
    if group_name:
        group.group_name = group_name
    # 群组描述更新
    if group_desc:
        group.group_desc = group_desc
    # 群组头像更新
    if group_avatar:
        _, extension = os.path.splitext(group_avatar.name)
        group_avatar_path = 'group/{uuid}_{extension}'.format(uuid=shortuuid.uuid(), extension=extension)
        if default_storage.exists(group_avatar_path):
            default_storage.delete(group_avatar_path)
        default_storage.save(group_avatar_path, group_avatar)
        group.group_avatar = group_avatar_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
    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.NO_CLOSE_PERMISSION)

    # 群组解锁
    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', ''))  # UTC, %Y-%m-%dT%H:%M:%SZ
    gather_lon = request.POST.get('lon', '')  # 经度
    gather_lat = request.POST.get('lat', '')  # 纬度

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

    # 权限校验
    if not GroupUserInfo.objects.filter(group_id=group_id, user_id=admin_id, subadmin=True, status=True).exists():
        return response(GroupStatusCode.NO_UPDATE_PERMISSION)

    # 集合信息设置
    group.gather_at = gather_at
    group.gather_lon = gather_lon
    group.gather_lat = gather_lat
    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,
    }, 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', '')

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

    return response(200, 'Generate Token Success', u'生成票据成功', {
        'token': r.token(group_id + admin_id, ex_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', '')

    # 获取旅行团唯一标识
    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 GroupUserInfo.objects.filter(group_id=group_id, user_id=admin_id, admin=True, status=True).exists():
        return response(GroupStatusCode.NO_TRANSFER_PERMISSION)

    # 群组用户记录创建，若记录不存在，则创建，若记录已存在，则更新
    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.save()

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

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