#!/usr/bin/env python
# coding=utf-8
import json

from django.db import transaction

from gm_types.doctor import DOCTOR_REGISTER_STATUS
from rpc.decorators import bind, bind_context
from rpc.exceptions import RPCNotFoundException
from rpc.tool.error_code import CODES, gen

from api.models import City, Province

from api.tool.verification_code import DocRegCode
from api.tool.sms_tool import send_vericode

from hippo.models import Doctor, Merchant
from hippo.models import DoctorRegister
from hippo.models import DoctorRegisterRecord


@bind('doctor/regcode/send')
def register_code_send(phone):
    """发送注册验证码
    """
    code = DocRegCode.generate(phone)
    send_vericode(phone, code)
    return gen(CODES.SUCCESS)


@bind('doctor/regcode/verify')
def register_code_verify(phone, code):
    """验证注册验证码
    """
    verified = DocRegCode.verify(code, phone)
    if verified:
        return gen(CODES.SUCCESS)
    return gen(CODES.INVALID_CODE)


@bind('doctor/register/cities')
def choices_cities():
    provinces_data = []
    provinces = Province.objects.all()
    for province in provinces:
        cities = City.objects.filter(province_id=province.id)
        item = {
            'id': province.id,
            'name': province.name,
            'cities': [{
                'id': city.id,
                'name': city.name,
            } for city in cities]
        }
        provinces_data.append(item)
    return {
        'provinces': provinces_data,
    }


@bind_context('doctor/register/create_or_update', login_required=True)
def create_or_update_register(ctx, reg_info, merchant_id=None):
    person_id = ctx.session.user.person.id.hex if not merchant_id else reg_info['person_id']

    record_content = json.dumps(reg_info)
    is_updated = False

    hospital_pics = reg_info.pop('hospital_pics', [])
    b_licences = reg_info.pop('b_licences', [])
    p_licences = reg_info.pop('p_licences', [])
    profession_licences = reg_info.pop('profession_licences', [])
    if merchant_id:
        mr = Merchant.objects.get(id=merchant_id)
        reg_info['merchant_id'] = merchant_id
        reg_info['business_partener'] = mr.doctor.business_partener
        reg_info['business_group'] = mr.doctor.business_group
        reg_info['related_hospital'] = mr.doctor.hospital
        doctorregister_id = reg_info.pop('doctorregister_id')
    with transaction.atomic():
        change_fields = []
        try:
            # 若是有外键关联的，需要重新赋值一下
            city_id = reg_info.pop('city_id', None)
            city = City.objects.get(id=city_id) if city_id else None
            reg_info['city'] = city
            if merchant_id:
                register = DoctorRegister.objects.get(id=doctorregister_id)
            else:
                register = DoctorRegister.objects.get(person_id=person_id)
            if register.status not in [DOCTOR_REGISTER_STATUS.DATA_REJECT, DOCTOR_REGISTER_STATUS.OLD_DATA]:
                # 已存在, 只有被拒绝之后才能修改
                raise Exception
            reg_info['status'] = DOCTOR_REGISTER_STATUS.DATA_SUBMITTED
            for k, v in reg_info.iteritems():
                if v != getattr(register, k):
                    change_fields.append(k)
                setattr(register, k, v)
            register.save()
            is_updated = True
        except DoctorRegister.DoesNotExist:
            # 不存在，新建
            reg_info['person_id'] = person_id
            drs = DoctorRegister.objects.filter(person_id=reg_info['person_id'])
            if drs.exists():
                raise gen(CODES.USER_ALREADY_EXIST)
            reg_info['status'] = DOCTOR_REGISTER_STATUS.DATA_SUBMITTED
            register = DoctorRegister.objects.create(**reg_info)

        b_change, p_change, t_change = register.update_licences(b_licences, p_licences, profession_licences)
        # 只有更新的情况下才标红字段
        if is_updated and b_change:
            change_fields.append('b_licences')
        if is_updated and p_change:
            change_fields.append('p_licences')
        h_change = register.update_hospital_pics(hospital_pics)
        if is_updated and h_change:
            change_fields.append('hospital_pics')
        if is_updated and t_change:
            change_fields.append('profession_licences')
        # 插入注册操作记录
        DoctorRegisterRecord.objects.create(
            doctor_register_id=register.id, status=reg_info['status'],
            content=record_content, change_fields=json.dumps(change_fields),
            handler_id=person_id
        )
        if merchant_id:
            register.merchant_id = merchant_id
        else:
            register.is_merchant = True
        register.save()

    return {'register_id': register.id if register else ''}


@bind('doctor/register/progress')
def register_progress(person_id):
    """
        获取医生注册进度
    """
    data = {}
    dg = None
    try:
        dg = DoctorRegister.objects.get(person_id=person_id)
    except DoctorRegister.DoesNotExist:
        pass

    if dg:
        data.update({
            'register_id': dg.id,
            'status': dg.status,
            'doctor_type': dg.doctor_type,
            'area_type': dg.area_type,
            'reject_reason': u'',
        })

        if dg.status == DOCTOR_REGISTER_STATUS.DATA_REJECT:
            record = DoctorRegisterRecord.objects.filter(doctor_register_id=dg.id).last()
            if record:
                data['reject_reason'] = record.reject_reason

    try:
        doctor = Doctor.objects.get(user__person__id=person_id)
        data['doctor_id'] = doctor.id  # 老数据有医生没有注册数据
    except Doctor.DoesNotExist:
        pass

    return data


@bind('doctor/register/get')
def get_register(person_id):
    reg = DoctorRegister.objects.filter(person_id=person_id).last()
    if not reg:
        raise RPCNotFoundException
    return reg.data()


@bind('doctor/register/get_by_id')
def get_register_by_id(doctorregister_id):
    reg = DoctorRegister.objects.get(id=doctorregister_id)
    if not reg:
        raise RPCNotFoundException
    data = reg.data()
    if data['status'] == DOCTOR_REGISTER_STATUS.DATA_REJECT:
        try:
            record = DoctorRegisterRecord.objects.filter(doctor_register=reg,status=DOCTOR_REGISTER_STATUS.DATA_REJECT).last()
            reason = record.reject_reason
        except:
            reason = ''
    else:
        reason = ''
    data['reason'] = reason
    return data

