# coding=utf-8
"""免费招募活动"""
import datetime
import time

from django.utils import timezone

from django.forms import model_to_dict
from gm_types.error import ERROR as ERROR_CODES
from gm_types.hera import ORDER_STATUS
from gm_types.gaia import FREER_RECRUITMENT_PUSH_TYPE, ACTIVITY_TYPE_ENUM

from api.manager.service_info_manager import get_toc_spu_info_list_mapping_by_spu_ids
from api.models.freerecruitment import FreeRecruitment, FreeRecruitmentDiary, FreeRecruitmentDoctor
from api.models.freerecruitment import ReservationUser
from api.models.freerecruitment import AssistanceUser
from api.models.freerecruitment import FreeRecruitmentUser
from api.models.freerecruitment import ThirdAccountInfo
from api.models.freerecruitment import FreeRecruitment, FreeRecruitmentImage, FreeRecruitmentUser
from hippo.models import Doctor, Doctor_Extra
from rpc.decorators import bind_context, bind
from rpc.tool.error_code import gen
from api.tool.user_tool import get_user_from_context
from api.models import AssistPrize, AssistCode, Assister, AssistThirdInfo, Service, BannerFreeRecruitment


@bind_context('api/freerecruitment/activity')
def freerecruitment_activity(ctx, activity_id):
    """免费招募活动信息获取。"""

    user = get_user_from_context(ctx)

    try:
        activity = FreeRecruitment.objects.get(pk=activity_id)
    except FreeRecruitment.DoesNotExist:
        gen(ERROR_CODES.ACTIVITY_NOT_EXIST)

    if not activity.is_online:
        gen(ERROR_CODES.ACTIVITY_OFFLINE)

    free_recruitment_user = reservation_user = False
    if user:
        # 报名用户
        free_recruitment_user = FreeRecruitmentUser.objects.filter(user_id=user.id, freerecruitment_id=activity_id).exists()
        if not free_recruitment_user:
            # 预约用户
            reservation_user = ReservationUser.objects.filter(user_id=user.id, freerecruitment_id=activity_id).exists()

    participation_status = 1
    if free_recruitment_user:
        participation_status = 3
    elif reservation_user:
        participation_status = 2

    try:
        service = Service.objects.get(id=activity.service_id)
    except:
        service = None

    num = FreeRecruitmentUser.objects.filter(freerecruitment_id=activity_id).count()

    detail_info = model_to_dict(activity)
    detail_info['button_num'] = int(1 + int(activity.service_id) % 30 + 2.3 * num+0.5)

    detail_info['details_banner'] = list(FreeRecruitmentImage.objects.filter(freerecruitment_id=activity_id).values_list('image', flat=True))
    detail_info['diary_ids'] = list(FreeRecruitmentDiary.objects.filter(freerecruitment_id=activity_id).values_list('diary_id', flat=True))
    doctor_ids = list(FreeRecruitmentDoctor.objects.filter(freerecruitment_id=activity_id).values_list('doctor_id', flat=True))
    related_doctor = []
    for doctor_id in doctor_ids:
        doctor = Doctor.objects.filter(id=doctor_id).first()
        doctor_extra = Doctor_Extra.objects.filter(doctor_id=doctor_id).first()
        related_doctor.append({
            'doctor_name': doctor.name,
            'portrait': doctor.portrait,
            'title': doctor.title,
            'introduction': doctor.introduction,
            'good_at': doctor.good_at,
            'working_year': doctor_extra.working_year if doctor_extra else 0
        })
    detail_info['related_doctor'] = related_doctor

    start_time = detail_info.pop('start_time')
    end_time = detail_info.pop('end_time')
    now = datetime.datetime.now()
    detail_info['start_time'] = time.mktime(time.strptime(str(start_time), "%Y-%m-%d %H:%M:%S"))
    detail_info['end_time'] = time.mktime(time.strptime(str(end_time), "%Y-%m-%d %H:%M:%S"))
    detail_info['now'] = time.time()
    if start_time <= now and end_time >= now:
        detail_info['status'] = ORDER_STATUS.ON
    elif start_time > now:
        detail_info['status'] = ORDER_STATUS.CLOSED
    else:
        detail_info['status'] = ORDER_STATUS.NOT_START

    detail_info['participation_status'] = participation_status

    services_info_dic = get_toc_spu_info_list_mapping_by_spu_ids([activity.service_id])
    recommend_services = [services_info_dic[str(sid)]
                          for sid in [activity.service_id] if str(sid) in services_info_dic]

    detail_info['hospital_name'] = service.doctor.hospital.name if service.doctor.hospital else ''
    detail_info['hospital_portrait'] = service.doctor.hospital.get_hospital_portrait() if service.doctor.hospital else ''
    detail_info['recommend_services_infos'] = recommend_services

    can_sold_item_ids = service._queryset_can_sell_items().values_list('id', flat=True)
    gengmei_price = Service.get_price_range_from_item_ids(can_sold_item_ids)['gengmei_price'][1]
    detail_info['original_price'] = gengmei_price
    detail_info['address'] = service.doctor.hospital.city.name if service.doctor.hospital.city else ''

    return detail_info


@bind_context('api/freerecruitment/activity/participation')
def freerecruitment_activity_participation(ctx, activity_id, user_id):
    """用户参与活动的助力情况。

    :params: user_id 参与活动的用户user_id
    """

    user = get_user_from_context(ctx)
    if not user_id and user:
        user_id = user.id

    if not user_id:
        gen(ERROR_CODES.PARAMS_INCOMPLETE)

    try:
        activity = FreeRecruitment.objects.get(pk=activity_id)
    except FreeRecruitment.DoesNotExist:
        gen(ERROR_CODES.ACTIVITY_NOT_EXIST)

    if not activity.is_online:
        gen(ERROR_CODES.ACTIVITY_OFFLINE)

    vote_num = AssistanceUser.objects.filter(
        freerecruitment_id=activity_id,
        user_id=user_id,
    ).count()

    voted = False
    if user:
        voted = AssistanceUser.objects.filter(
            freerecruitment_id=activity_id,
            user_id=user_id,
            assister_id=user.id
        ).exists()

    data = {
        'vote_num': vote_num,
        'voted': voted,
    }

    return data


@bind_context('api/freerecruitment/activity/assist')
def freerecruitment_activity_assist(ctx, activity_id, user_id, form_id):
    """用户参与活动的助力。

    :params: user_id 参与活动的用户user_id
    """

    user = get_user_from_context(ctx)
    if not user:
        gen(ERROR_CODES.LOGIN_REQUIRED)

    try:
        activity = FreeRecruitment.objects.get(pk=activity_id)
    except FreeRecruitment.DoesNotExist:
        gen(ERROR_CODES.ACTIVITY_NOT_EXIST)

    if not activity.is_online:
        gen(ERROR_CODES.ACTIVITY_OFFLINE)

    now = timezone.now()
    if activity.start_time and now < activity.start_time:
        gen(ERROR_CODES.ACTIVITY_NOT_STARTED)
    elif activity.end_time and now > activity.end_time:
        gen(ERROR_CODES.ACTIVITY_CLOSED)

    _, created = AssistanceUser.objects.update_or_create(
        freerecruitment_id=activity_id,
        user_id=user_id,
        assister_id=user.id,
    )
    if not created:
        gen(ERROR_CODES.SIGN_HAS_ASSIST)

    if form_id:
        ThirdAccountInfo.upsert(
            push_type=FREER_RECRUITMENT_PUSH_TYPE.VOTED,
            activity_id=activity_id,
            user_id=user.id,
            form_id=form_id,
        )

    return


@bind_context('api/freerecruitment/recornd_thirdinfo')
def freerecruitment_recornd_thirdinfo(ctx, activity_id, form_id):
    """用户参与活动的助力。

    :params: user_id 参与活动的用户user_id
    """

    user = get_user_from_context(ctx)
    if not user:
        gen(ERROR_CODES.LOGIN_REQUIRED)

    # 用于被投票push
    if form_id:
        ThirdAccountInfo.upsert(
            push_type=FREER_RECRUITMENT_PUSH_TYPE.VOTED,
            activity_id=activity_id,
            user_id=user.id,
            form_id=form_id,
        )

    return


@bind_context('api/freerecruitment/get_info')
def get_indo(ctx, page):
    '''
    获取列表页数据
    '''

    data = {}
    list_banner = BannerFreeRecruitment.get_banners(page_type=0)['banner_list']
    data['list_banner'] = []
    for i in list_banner:
        if i['icon'] != '':
            data['list_banner'].append(i)

    list_info = []
    now = datetime.datetime.now()
    underway_info = FreeRecruitment.objects.filter(start_time__lte=now, end_time__gte=now, is_online=True).order_by('-start_time')  #筛选正在进行的活动
    start_right = FreeRecruitment.objects.filter(start_time__gt=now, is_online=True).order_by('-start_time')  #筛选即将开始的活动
    has_expired = FreeRecruitment.objects.filter(end_time__lt=now, is_online=True).order_by('end_time')  #筛选已经过期的活动
    for u in underway_info:
        service = Service.objects.filter(id=u.service_id).first()
        num = FreeRecruitmentUser.objects.filter(freerecruitment_id=u.id).count()
        can_sold_item_ids = service._queryset_can_sell_items().values_list('id', flat=True)
        gengmei_price = Service.get_price_range_from_item_ids(can_sold_item_ids)['gengmei_price'][1]
        list_info.append({
            'id': u.id,
            'list_image': u.list_image,
            'title': u.title,
            'address': service.doctor.hospital.city.name if service.doctor.hospital and service.doctor.hospital.city else '',   #地址
            'deposit': u.deposit,
            'original_price': gengmei_price,   #原价
            'quota': u.quota,
            'status': ORDER_STATUS.ON,   # 1 正在进行
            'button_num': int(1+int(u.service_id)%30+2.3*num+0.5),  #按钮数字
            'present_price': 0,
        })
    for s in start_right:
        service = Service.objects.filter(id=s.service_id).first()
        num = FreeRecruitmentUser.objects.filter(freerecruitment_id=s.id).count()
        can_sold_item_ids = service._queryset_can_sell_items().values_list('id', flat=True)
        gengmei_price = Service.get_price_range_from_item_ids(can_sold_item_ids)['gengmei_price'][1]
        list_info.append({
            'id': s.id,
            'list_image': s.list_image,
            'title': s.title,
            'address': service.doctor.hospital.city.name if service.doctor.hospital and service.doctor.hospital.city else '',   #地址
            'deposit': s.deposit,
            'original_price': gengmei_price,   #原价
            'quota': s.quota,
            'status': ORDER_STATUS.CLOSED,   # 2 即将开始
            'button_num': int(1+int(s.service_id)%30+2.3*num+0.5),  #按钮数字
            'present_price': 0,
        })
    for h in has_expired:
        service = Service.objects.filter(id=h.service_id).first()
        num = FreeRecruitmentUser.objects.filter(freerecruitment_id=h.id).count()
        can_sold_item_ids = service._queryset_can_sell_items().values_list('id', flat=True)
        gengmei_price = Service.get_price_range_from_item_ids(can_sold_item_ids)['gengmei_price'][1]
        list_info.append({
            'id': h.id,
            'list_image': h.list_image,
            'title': h.title,
            'address': service.doctor.hospital.city.name if service.doctor.hospital and service.doctor.hospital.city else '',   #地址
            'deposit': h.deposit,
            'original_price': gengmei_price,   #原价
            'quota': h.quota,
            'status': ORDER_STATUS.NOT_START,   # 3 已经过期
            'button_num': int(1+int(h.service_id)%30+2.3*num+0.5),  #按钮数字
            'present_price': 0,
        })
    start_num = page*10
    data['list_info'] = list_info[start_num: start_num + 10]
    return data

@bind_context('api/freerecruitment/sign_up')
def freerecruitment_activity_sign_up(ctx, registration_data):
    """用户报名

    :params: user_id 参与活动的用户user_id
    """

    user = get_user_from_context(ctx)
    if not user:
        gen(ERROR_CODES.LOGIN_REQUIRED)

    form_id = registration_data['form_id']
    activity_id = registration_data['freerecruitment_id']

    freerecruitmentuser, _ = FreeRecruitmentUser.objects.get_or_create(
        freerecruitment_id=registration_data['freerecruitment_id'],
        user_id=user.id,
        name=registration_data['name'],
        sex=registration_data['sex'],
        age=registration_data['age'],
        user_phone=registration_data['user_phone'],
        full_face_photo=registration_data['full_face_photo'],
        left_45_degrees=registration_data['left_45_degrees'],
        right_45_degrees=registration_data['right_45_degrees'],
        left_image=registration_data['left_image'],
        right_image=registration_data['right_image'],
        has_cosmetic_history=registration_data['has_cosmetic_history'],
        has_medical_history=registration_data['has_medical_history'],
    )

    # 用于活动结束push
    if activity_id and form_id:
        ThirdAccountInfo.upsert(
            push_type=FREER_RECRUITMENT_PUSH_TYPE.ACTIVITY_ENDED,
            activity_id=activity_id,
            user_id=user.id,
            form_id=form_id,
        )

    return freerecruitmentuser.id

@bind_context('api/freerecruitment/reminder_registration')
def freerecruitment_activity_reminder_registration(ctx, reminder_data):
    """提醒报名    预约用户

    :params: user_id 参与活动的用户user_id
    """

    user = get_user_from_context(ctx)
    if not user:
        gen(ERROR_CODES.LOGIN_REQUIRED)

    reservationuser, _ = ReservationUser.objects.get_or_create(
        freerecruitment_id=reminder_data['freerecruitment_id'],
        user_id=reminder_data['user_id'],
    )

    # 用于活动开始push
    form_id = reminder_data['form_id']
    if form_id:
        ThirdAccountInfo.upsert(
            push_type=FREER_RECRUITMENT_PUSH_TYPE.ACTIVITY_STARTED,
            activity_id=reminder_data['freerecruitment_id'],
            user_id=user.id,
            form_id=form_id,
        )

    return reservationuser.id

