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

from __future__ import division

import os

import shortuuid
from curtail_uuid import CurtailUUID
from django.conf import settings
from django.contrib.auth.hashers import check_password
from django.core.files.storage import default_storage
from django.db import transaction
from isoweek import Week
from logit import logit
from TimeConvert import TimeConvert as tc

from account.models import LensmanInfo, UserIncomeExpensesInfo, UserInfo
from group.models import GroupInfo, GroupPhotoInfo, GroupPhotoOrderInfo
from message.models import SystemMessageInfo
from pay.models import OrderInfo
from photo.models import PhotosInfo
from utils.error.errno_utils import LensmanStatusCode, OrderStatusCode, UserStatusCode
from utils.error.response_utils import response
from utils.message_utils import system_messages
from utils.page_utils import pagination
from utils.redis.rbrief import set_brief_info
from utils.redis.rgroup import set_group_info
from utils.redis.rkeys import GROUP_LAST_PHOTO_PK, TODAY_INCOME, TODAY_UPLOAD_PHOTO_AMOUNT, WEEK_INCOME, WEEK_SOLD
from utils.redis.rorder import set_lensman_order_record
from utils.redis.rprice import get_lensman_price_fixed, set_lensman_price_fixed
from utils.redis.rprofile import set_profile_info
from utils.thumbnail_utils import make_thumbnail
from utils.watermark_utils import watermark_wrap


r = settings.REDIS_CACHE


@logit
def lensman_submit_api(request):
    """ 摄影师信息提交 """
    unionid = request.POST.get('unionid', '')
    openid = request.POST.get('openid', '')
    phone = request.POST.get('phone', '')

    if LensmanInfo.objects.filter(phone=phone).exclude(unionid=unionid).exists():
        return response(LensmanStatusCode.LENSMAN_PHONE_ALREADY_EXISTS)

    fields = {
        'name': request.POST.get('name', ''),
        'sex': int(request.POST.get('sex', 1)),
        'phone': phone,
        'location': request.POST.get('location', ''),
        'user_status': LensmanInfo.UNVERIFIED,
    }

    lensman, created = LensmanInfo.objects.get_or_create(unionid=unionid, defaults=fields)
    # 状态为 UNVERIFIED 的允许修改, 其他需要登录摄影师 APP 进行信息的修改
    if lensman.user_status not in [LensmanInfo.UNVERIFIED, LensmanInfo.REFUSED]:
        return response(LensmanStatusCode.LENSMAN_ALREADY_NOT_UNVERIFIED)
    if not created:
        for key, value in fields.iteritems():
            setattr(lensman, key, value)
        lensman.save()

    return response(200, 'Submit Success', u'提交成功', {})


@logit
def lensman_login_api(request):
    """ 摄影师登录 """
    username = request.POST.get('username', '')
    password = request.POST.get('password', '')

    try:
        lensman = LensmanInfo.objects.get(username=username)
    except LensmanInfo.DoesNotExist:
        return response(LensmanStatusCode.LENSMAN_NOT_FOUND)

    if not check_password(password, lensman.encryption):
        return response(LensmanStatusCode.LENSMAN_PASSWORD_ERROR)

    try:
        user = UserInfo.objects.get(user_id=lensman.lensman_id)
    except UserInfo.DoesNotExist:
        return response(LensmanStatusCode.LENSMAN_NOT_FOUND)

    return response(200, 'Login Success', u'登录成功', user.data)


@logit
def lensman_wx_authorize_api(request):
    unionid = request.POST.get('unionid', '')
    openid = request.POST.get('openid', '')

    sex = request.POST.get('sex', 0)
    nickname = request.POST.get('nickname', '') or request.POST.get('screen_name', '')
    avatar = request.POST.get('headimgurl', '') or request.POST.get('profile_image_url', '')
    country = request.POST.get('country', '')
    province = request.POST.get('province', '')
    city = request.POST.get('city', '')

    try:
        user = UserInfo.objects.get(unionid=unionid)
    except UserInfo.DoesNotExist:
        return response(LensmanStatusCode.LENSMAN_NOT_FOUND)

    if user.user_status != UserInfo.ACTIVATED:
        return response(LensmanStatusCode.LENSMAN_NOT_ACTIVATED)

    user.openid = openid
    user.sex = sex
    user.nickname = nickname
    user.avatar = avatar
    user.country = country
    user.province = province
    user.city = city
    user.save()

    set_profile_info(user)

    return response(200, 'Lensman Login Success', u'摄影师登录成功', user.data)


@logit
def lensman_price_fix_api(request):
    lensman_id = request.POST.get('user_id', '')
    nomark = request.POST.get('nomark', 299)
    origin = request.POST.get('origin', 999)

    # 用户校验
    try:
        lensman = LensmanInfo.objects.get(lensman_id=lensman_id)
    except LensmanInfo.DoesNotExist:
        return response(UserStatusCode.USER_NOT_FOUND)

    if 'nomark' in request.POST:
        lensman.nomark = nomark
    if 'origin' in request.POST:
        lensman.origin = origin
    lensman.save()

    set_lensman_price_fixed(lensman_id)

    return response(200, 'Lensman Price Fix Success', u'摄影师定价修改成功')


@logit
def lensman_photo_upload_api(request):
    """ 摄影师照片上传 """
    user_id = lensman_id = request.POST.get('user_id', '')
    nickname = request.POST.get('nickname', '')
    group_id = request.POST.get('group_id', '')
    session_id = request.POST.get('session_id', '')

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

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

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

    if not group_id:
        # 判断通过 session_id 创建的群组是否存在，如果不存在，则直接创建
        group, group_created = GroupInfo.objects.get_or_create(session_id=session_id, group_from=GroupInfo.SESSION_GROUP, defaults={
            'group_id': CurtailUUID.uuid(GroupInfo, 'group_id'),
            'admin_id': user_id,
            'group_name': user.final_nickname,
            'group_default_avatar': 0,
        })

        # Redis 群组数据缓存
        if group_created:
            set_group_info(group)

        group_id = group.group_id

    # # 判断 group_id/user_id 的群组用户是否存在，如果不存在，则直接创建
    # group_user_current_id = -1
    # group_user, group_user_created = GroupUserInfo.objects.get_or_create(group_id=group_id, user_id=user_id, defaults={
    #     'current_id': group_user_current_id,  # 通过扫描 session_id 二维码进群的用户，默认可以查看该群组所有照片
    #     'nickname': nickname or user.final_nickname,
    #     'avatar': user.avatar,
    #     'admin': group_created,
    #     'user_status': GroupUserInfo.PASSED,
    #     'passed_at': tc.utc_datetime(),
    # })
    # if not group_user_created:
    #     group_user.current_id = group_user_current_id
    #     group_user.user_status = GroupUserInfo.PASSED
    #     group_user.save()
    #
    # # Redis 群组用户数据缓存
    # set_group_users_info(group) if group_user_created else get_group_users_info(group_id, user_id)

    if photo:
        # 写 PhotosInfo 表
        _, extension = os.path.splitext(photo.name)
        extension = extension or 'jpeg'

        m_photo_path = 'photo/{uuid}{extension}'.format(uuid=shortuuid.uuid(), extension=extension)

        if default_storage.exists(m_photo_path):
            default_storage.delete(m_photo_path)
        default_storage.save(m_photo_path, photo)

        p_photo_path = 'photo/{uuid}{extension}'.format(uuid=shortuuid.uuid(), extension=extension)
        watermark_wrap(
            os.path.join(settings.MEDIA_ROOT, m_photo_path).replace('\\', '/'),
            settings.WATERMARK_LOGO,
            os.path.join(settings.MEDIA_ROOT, p_photo_path).replace('\\', '/')
        )

        photo, created = PhotosInfo.objects.get_or_create(
            lensman_id=lensman_id,
            session_id=session_id,
            photo_id=photo_id,
        )
        photo.p_photo_path = p_photo_path
        photo.m_photo_path = m_photo_path
        photo.save()

        # 写 GroupPhotoInfo 表
        photo_path = photo.p_photo_path
        photo_thumbnail_path = photo_path.replace('.', '_thumbnail.')
        photo_thumbnail2_path = photo_path.replace('.', '_thumbnail2.')

        # 群组照片缩略图生成
        # 双列: 540, 40-50K
        photo_w, photo_h, photo_thumbnail_w, photo_thumbnail_h = make_thumbnail(
            os.path.join(settings.MEDIA_ROOT, photo_path).replace('\\', '/'),
            os.path.join(settings.MEDIA_ROOT, photo_thumbnail_path).replace('\\', '/'),
            settings.THUMBNAIL_MAX_WIDTH
        )

        # 单列: 1080, xx-100K
        photo_w, photo_h, photo_thumbnail2_w, photo_thumbnail2_h = make_thumbnail(
            os.path.join(settings.MEDIA_ROOT, photo_path).replace('\\', '/'),
            os.path.join(settings.MEDIA_ROOT, photo_thumbnail2_path).replace('\\', '/'),
            settings.THUMBNAIL_MAX_WIDTH2
        )

        # 群组照片记录创建
        group_photo = GroupPhotoInfo.objects.create(
            group_id=group_id,
            user_id=user_id,
            nickname=user.final_nickname,
            avatar=user.avatar,
            photo_path=photo_path,
            photo_w=photo_w,
            photo_h=photo_h,
            photo_thumbnail_path=photo_thumbnail_path,
            photo_thumbnail_w=photo_thumbnail_w,
            photo_thumbnail_h=photo_thumbnail_h,
            photo_thumbnail2_path=photo_thumbnail2_path,
            photo_thumbnail2_w=photo_thumbnail2_w,
            photo_thumbnail2_h=photo_thumbnail2_h,
            photo_from=GroupPhotoInfo.SESSION_GROUP,
            session_id=photo.session_id,
            lensman_id=photo.lensman_id,
            lensman_photo_id=photo.photo_id,
        )

        # 设置群组最后一张照片PK
        r.set(GROUP_LAST_PHOTO_PK % group_id, group_photo.pk)

        # 更新今日上传照片数量
        r.incr(TODAY_UPLOAD_PHOTO_AMOUNT % (user_id, tc.local_string(format='%Y%m%d')))

    return response(200, 'Lensman Upload Photo Success', u'摄影师照片上传成功', {
        'group_id': group_id,
    })


@logit
@transaction.atomic
def lensman_origin_photo_upload_api(request):
    order_id = request.POST.get('order_id', '')

    user_id = lensman_id = request.POST.get('user_id', '')
    session_id = request.POST.get('session_id', '')

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

    deleted = int(request.POST.get('deleted', 0))

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

    try:
        order = OrderInfo.objects.select_for_update().get(order_id=order_id, pay_status=OrderInfo.PAID)
    except OrderInfo.DoesNotExist:
        return response(OrderStatusCode.WX_ORDER_NOT_FOUND)

    # 原图已删除, 处理退款逻辑
    if deleted and order.photo_status == OrderInfo.WANTED:
        # 用户余额增加
        try:
            from_user = UserInfo.objects.select_for_update().get(user_id=order.from_uid)
        except UserInfo.DoesNotExist:
            pass

        if from_user:
            # 余额增加
            from_user.balance += order.total_fee
            from_user.save()
            # 余额记录
            UserIncomeExpensesInfo.objects.create(
                user_id=order.from_uid,
                photo_id=order.photo_id,
                type=UserIncomeExpensesInfo.INCOME,
                amount=order.total_fee,
                balance=from_user.balance,
                freeze_income_amount=0,
                freeze_income_balance=from_user.freeze_income_balance,
                remark=u'高清图购买退款',
            )

        # 摄影师余额减少
        try:
            to_user = UserInfo.objects.select_for_update().get(user_id=order.to_uid)
        except UserInfo.DoesNotExist:
            pass

        if to_user:
            # 余额减少
            to_user.freeze_income_balance -= order.total_fee
            to_user.save()
            # 余额记录
            UserIncomeExpensesInfo.objects.create(
                user_id=order.to_uid,
                photo_id=order.photo_id,
                type=UserIncomeExpensesInfo.EXPENSE,
                amount=order.total_fee,
                balance=to_user.balance,
                freeze_income_amount=0,
                freeze_income_balance=to_user.freeze_income_balance,
                remark=u'高清图购买退款',
            )

        # 更新订单状态
        order.photo_status = OrderInfo.DELETED
        order.reback_status = True
        order.reback_at = tc.utc_datetime()
        order.save()

    if photo:
        # 写 PhotosInfo 表
        _, extension = os.path.splitext(photo.name)
        extension = extension or 'jpeg'

        r_photo_path = 'photo/{uuid}{extension}'.format(uuid=shortuuid.uuid(), extension=extension)

        if default_storage.exists(r_photo_path):
            default_storage.delete(r_photo_path)
        default_storage.save(r_photo_path, photo)

        PhotosInfo.objects.filter(
            lensman_id=lensman_id,
            session_id=session_id,
            photo_id=photo_id,
        ).update(
            r_photo_path=r_photo_path
        )

        porder, created = GroupPhotoOrderInfo.objects.select_for_update().get_or_create(
            group_id=order.group_id,
            session_id=session_id,
            user_id=order.from_uid,
            photo_id=order.photo_id,
            lensman_photo_id=photo_id,
        )
        porder.r_photo_path = r_photo_path
        porder.save()

        set_lensman_order_record(porder)

        # 摄影师余额解冻
        try:
            to_user = UserInfo.objects.select_for_update().get(user_id=order.to_uid)
        except UserInfo.DoesNotExist:
            pass

        if to_user:
            # 余额解冻
            to_user.balance += order.total_fee
            to_user.freeze_income_balance -= order.total_fee
            to_user.save()
            # Redis 数值更新
            set_brief_info(order.to_uid, order.photo_type, order.total_fee, dt=order.created_at)
            # 余额记录
            UserIncomeExpensesInfo.objects.create(
                user_id=order.to_uid,
                photo_id=order.photo_id,
                type=UserIncomeExpensesInfo.UNFREEZE,
                amount=order.total_fee,
                balance=to_user.balance,
                freeze_income_amount=order.total_fee,
                freeze_income_balance=to_user.freeze_income_balance,
                remark=u'高清图购买退款',
            )

        order.photo_status = OrderInfo.FETCHED
        order.save()

    return response(200, 'Lensman Upload Origin Photo Success', u'摄影师照片高清图上传成功')


@logit
def lensman_brief_api(request):
    user_id = request.POST.get('user_id', '')

    ymd = tc.local_string(format='%Y%m%d')
    week = Week.thisweek().isoformat()

    # 周收入
    origin_week_income = int(r.get(WEEK_INCOME % (user_id, OrderInfo.ORIGIN, week)) or 0)
    # 日收入
    nomark_today_income = int(r.get(TODAY_INCOME % (user_id, OrderInfo.NOMARK, ymd)) or 0)
    # 日上传
    today_upload = int(r.get(TODAY_UPLOAD_PHOTO_AMOUNT % (user_id, ymd)) or 0)
    # 周售出
    week_sold = int(r.get(WEEK_SOLD % (user_id, OrderInfo.ORIGIN, ymd)) or 0)

    # 摄影师端系统消息
    systems = system_messages(user_id, SystemMessageInfo.PAIAI_LENSMAN)
    systems, left = pagination(systems, 1, 10)
    systems = [msg.msg_info(user_id) for msg in systems]

    # 照片购买记录
    orders = OrderInfo.objects.filter(to_uid=user_id, pay_status=OrderInfo.PAID, status=True).order_by('-pk')
    orders, left = pagination(orders, 1, 10)
    orders = [order.data(user_id) for order in orders]

    # 获取摄影师定价
    price_fixed = get_lensman_price_fixed(user_id)

    return response(200, 'Get Lensman Brief Success', u'获取摄影师简报成功', {
        'origin_week_income': origin_week_income,
        'nomark_today_income': nomark_today_income,
        'today_upload': today_upload,
        'week_sold': week_sold,
        'messages': {
            'system': systems,
            'orders': orders,
        },
        'price_fixed': price_fixed,
    })


@logit
def lensman_origin_wanted_api(request):
    user_id = request.POST.get('user_id', '')

    orders = OrderInfo.objects.filter(
        to_uid=user_id,
        photo_type=OrderInfo.ORIGIN,
        photo_status=OrderInfo.WANTED,
        pay_status=OrderInfo.PAID,
        status=True
    ).order_by('pk')
    wanted = [order.lensdata for order in orders]

    return response(200, 'Get Origin Wanted Success', u'获取需要上传原图成功', {
        'wanted': wanted
    })
