#!/usr/bin/env python
# coding=utf-8
import datetime
from django.db import models
from django.utils import timezone
from django.db.models import Q
from django.contrib.auth.models import User

from gm_upload import IMG_TYPE, ImgUrlField
from gm_types.gaia import HOSPITAL_TYPE, DOCTOR_TYPE
from gm_types.doctor import DOCTOR_AREA_TYPE, DOCTOR_REGISTER_STATUS, DOCTOR_LICENCE_TYPE, DOCTOR_INFO_STATUS, \
    DOCTOR_TITLE_TYPE
from rpc.tool.error_code import gen, CODES

from api.models.person import Person
from api.models.area import City, Province
from api.models.doctor import DocBusinessRecord
from api.models.bodypart import BodyPart

from hippo.tool.user_tool import get_user_by_id, get_user_extra_by_user_id

from hippo.models import Doctor, Hospital


class DoctorRegister(models.Model):
    """
    用于医生注册
    """

    class Meta:
        app_label = 'doctor'
        db_table = 'doctor_doctorregister'
        verbose_name = u'医生注册'
        verbose_name_plural = u'医生注册'

    name = models.CharField(max_length=20, null=True, verbose_name=u'真实姓名', blank=True, default='')
    phone = models.CharField(max_length=20, verbose_name=u"联系手机号码", null=False)
    hospital = models.CharField(max_length=200, null=False, verbose_name=u"现工作医院医院")
    department = models.CharField(max_length=50, default="", help_text=u'所在科室')
    title = models.CharField(max_length=200, verbose_name=u"职称", choices=DOCTOR_TITLE_TYPE,
                             default=DOCTOR_TITLE_TYPE.EMPTY)
    good_at = models.TextField(blank=True, verbose_name="擅长项目")
    introduction = models.TextField(blank=True, help_text="简介")
    portrait = ImgUrlField(img_type=IMG_TYPE.DOCTOR, max_length=200, help_text=u"真实头像")
    add_time = models.DateTimeField(default=timezone.now, verbose_name=u'注册时间')
    assist_phone = models.CharField(max_length=20, verbose_name=u"助理手机号码", null=True, blank=True)

    business_partener = models.ForeignKey(
        User, default=None, null=True, verbose_name=u'负责此医生的商务同事',
        related_name='business_partener_register',
    )
    business_group = models.IntegerField('组织架构的组织', null=True)
    query_image = ImgUrlField(img_type=IMG_TYPE.DOCTORREGISTER, max_length=400, help_text=u"查询到的图片", blank=True,
                              default='')

    doctor_type = models.CharField(max_length=1, default=DOCTOR_TYPE.DOCTOR,
                                   choices=DOCTOR_TYPE, null=False,
                                   verbose_name=u'医生类型')
    # add by hera 1.12 hera583
    person = models.OneToOneField(Person, default=None, verbose_name=u'账号信息', null=True, related_name='doctor_register')

    # 注册流程重构时增加 at 2017-02-14
    city = models.ForeignKey(City, verbose_name=u'所在地', null=True, blank=True)
    address = models.CharField(max_length=200, verbose_name=u'所在地地址', null=True, blank=True)  # 境外手动填写的地址
    hospital_type = models.CharField(
        max_length=1, verbose_name=u'医院类型', default=HOSPITAL_TYPE.PRIVATE, choices=HOSPITAL_TYPE,
        null=True, blank=True
    )
    related_hospital = models.ForeignKey(Hospital, verbose_name=u'商务关联医院', null=True, blank=True)
    area_type = models.IntegerField(
        verbose_name=u'地域类型', choices=DOCTOR_AREA_TYPE, default=DOCTOR_AREA_TYPE.CISBORDER,
        null=True, blank=True
    )
    status = models.IntegerField(
        verbose_name=u'注册状态', choices=DOCTOR_REGISTER_STATUS, default=DOCTOR_REGISTER_STATUS.DATA_SUBMITTED
    )
    handler = models.ForeignKey(Person, related_name='handle_register', help_text=u"处理人", blank=True, null=True)
    is_agreement_checked = models.BooleanField(verbose_name=u'合同是否已审核', default=False)

    is_handled = models.BooleanField(default=False, verbose_name=u'是否已经处理', blank=True)  # 列表中展示还有用, 无关其他
    # <<<<<<<<废弃的 at 2017-02-14
    verify_phone = models.CharField(max_length=20, null=True, blank=True, default=None, verbose_name=u'核实电话(座机)')
    email = models.EmailField(max_length=100, verbose_name=u"个人邮箱", null=True, blank=True)
    profession_number = models.CharField(max_length=100, null=True, blank=True, help_text=u"医生职业号")
    inviter = models.CharField(max_length=20, null=True, verbose_name=u'邀请人', blank=True)
    comments = models.CharField(max_length=200, null=True, blank=True, verbose_name=u'备注')
    password = models.CharField(verbose_name=u'password', max_length=128, blank=True, default='', null=True)
    business_licence = ImgUrlField(img_type=IMG_TYPE.DOCTORREGISTER, max_length=400, help_text=u"资格证", blank=True,
                                   null=True)
    practice_licence = ImgUrlField(img_type=IMG_TYPE.DOCTORREGISTER, max_length=400, help_text=u"医生执业证", blank=True,
                                   null=True)
    editable = models.BooleanField(verbose_name=u'用户是否可修改', default=False)
    register_phone = models.CharField(max_length=20, verbose_name=u"注册手机号", null=True, blank=True)
    # >>>>>>>>>
    is_merchant = models.BigIntegerField(verbose_name=u'注册时是否为商户', default=False)
    merchant_id = models.BigIntegerField(verbose_name=u'创建此医生的商户ID', null=True, blank=True, default=None)
    doctor_id = models.CharField(verbose_name=u'创建医生之后对应的医生ID', max_length=100, null=True,
                                 blank=True, default=None)
    register_phone = models.CharField(max_length=20, verbose_name=u"登录手机号", null=True, blank=True)

    professional_certificate_num = models.CharField(verbose_name=u'医生执业证书编号', default='', max_length=100)

    update_time = models.DateTimeField(auto_now=True, verbose_name=u'更新时间', null=True)
    # b_licences_start = models.DateField(verbose_name=u'医生资格证有效期开始时间', null=True)
    # b_licences_end = models.DateField(verbose_name=u'医生资格证有效期结束时间', null=True)
    # p_licences_start = models.DateField(verbose_name=u'医生执业证有效期开始时间', null=True)
    # p_licences_end = models.DateField(verbose_name=u'医生执业证有效期结束时间', null=True)

    def organization_images(self):
        # TODO Deprecated see self.hospital_pics()
        """
            医院实景图片
        """
        images = []
        if self.doctor_type == DOCTOR_TYPE.OFFICER:
            image_list = RegisterOrganization.objects.filter(doctor_id=self.id)
            for item in image_list:
                images.append(item.image_url)
        return images

    def data(self):
        """
            用户输入的信息
        """
        city_id = self.city.id if self.city else None
        province_id = self.city.province.id if self.city else None

        try:
            city = City.objects.get(id=city_id)
            province = Province.objects.get(id=province_id)
            city = {'name': city.name, 'id': city.id}
            province = {'name': province.name, 'id': province.id}
        except:
            city = {}
            province = {}

        data = {
            'id': self.id,
            'doctor_type': self.doctor_type,
            'area_type': self.area_type,
            'city_id': city,
            'province_id': province,
            'address': self.address,
            'name': self.name,
            'portrait': self.portrait,
            'hospital_type': self.hospital_type,
            'title': self.title,
            'department': self.department,
            'phone': self.phone,
            'assist_phone': self.assist_phone,
            'hospital': self.hospital,
            'introduction': self.introduction,
            'good_at': self.good_at,
            'b_licences': self.b_licences,
            'p_licences': self.p_licences,
            'hospital_pics': self.hospital_pics(),
            'profession_licences': self.t_licences,
            'status': self.status,
            'register_phone': self.register_phone,
            'professional_certificate_num': self.professional_certificate_num,
        }
        return data

    def _licence_images(self, licence_type):
        """
        获取 机构的资质/执业证书照片
        注册申请通过，医生的证书关联Doctor / 机构管理者的证书关联Hospital，直接调用方法 doctor.update_licence_images
        """
        image_list = DoctorRegisterLicence.objects.filter(doctor_register_id=self.id, type=licence_type)
        images = [item.image_url for item in image_list]
        return images

    @property
    def b_licences(self):
        """资格证(医生)
        营业执照(医院)
        """
        return self._licence_images(DOCTOR_LICENCE_TYPE.BUSINESS)

    @property
    def p_licences(self):
        """执业证(医生)
        医疗机构执业许可证(机构)
        """
        return self._licence_images(DOCTOR_LICENCE_TYPE.PRACTICE)

    @property
    def t_licences(self):
        """职称证书"""
        return self._licence_images(DOCTOR_LICENCE_TYPE.TITLE)

    @property
    def agreement_image(self):
        """合同照片"""
        return [item.image_url for item in DoctorRegisterAgreement.objects.filter(doctor_register__id=self.id)]

    def update_licences(self, b_licences, p_licences, t_licences):
        """
        修改机构的资质/执业证书照片
        """
        b_change = self._update_licences(DOCTOR_LICENCE_TYPE.BUSINESS, b_licences)
        p_change = self._update_licences(DOCTOR_LICENCE_TYPE.PRACTICE, p_licences)
        t_change = self._update_licences(DOCTOR_LICENCE_TYPE.TITLE, t_licences)
        return b_change, p_change, t_change

    def _update_licences(self, licence_type, licences_images):
        if not licences_images and licence_type != DOCTOR_LICENCE_TYPE.TITLE:
            return

        old_images = set(DoctorRegisterLicence.objects.filter(
            doctor_register_id=self.id, type=licence_type
        ))
        change = False
        new_images = []
        for item in licences_images:
            objs = DoctorRegisterLicence.objects.filter(doctor_register_id=self.id, type=licence_type, image_url=item)
            if objs.exists():
                created = False
                obj = objs.first()
            else:
                obj = DoctorRegisterLicence.objects.create(doctor_register_id=self.id, type=licence_type, image_url=item)
                created = True
            # obj, created = DoctorRegisterLicence.objects.get_or_create(
            #     doctor_register_id=self.id, type=licence_type, image_url=item
            # )
            new_images.append(obj)
            change = change or created
        new_images = set(new_images)

        for item in (old_images - new_images):
            change = True
            item.delete()
        return change

    def hospital_pics(self):
        """
            医院实景图片
        """
        organizations = RegisterOrganization.objects.filter(doctor_id=self.id)
        images = [item.image_url for item in organizations]
        return images

    def update_hospital_pics(self, images):
        org_image = RegisterOrganization.objects.filter(doctor_id=self.id)
        change = False
        for url in images:
            _, created = RegisterOrganization.objects.get_or_create(doctor_id=self.id, image_url=url)
            change = change or created
        # 删除删除掉的条目
        row = org_image.filter(~Q(image_url__in=images)).count()
        if row > 0:
            change = True
        org_image.filter(~Q(image_url__in=images)).delete()
        return change

    def get_detail_info(self):
        """
        获取医生(医院)注册详情信息
        create by oldman at 2017-02-17
        :return:
        """
        if self.doctor_type == DOCTOR_TYPE.DOCTOR:
            return {
                'area_type': self.area_type,
                'address': self.address if self.area_type == DOCTOR_AREA_TYPE.ABROAD else
                (u'{}省 {}'.format(self.city.province.name, self.city.name) if self.city else ''),
                'user': self.person.user.last_name if self.person else '',
                'name': self.name,
                'portrait': self.portrait,
                'title': DOCTOR_TITLE_TYPE.getDesc(self.title),
                'hospital': self.hospital,
                'login_phone': self.person.phone if self.person else '',
                'related_phone': self.phone,
                'assist_phone': self.assist_phone,
                'b_licences': self.b_licences,
                'p_licences': self.p_licences,
                't_licences': self.t_licences,
                'introduction': self.introduction,
                'good_at': self.good_at,
                'status': self.status,
                'business_partener': self.business_partener.id if self.business_partener else None,
                'business_group': self.business_group,
                'related_hospital': self.related_hospital.id if self.related_hospital else None,
                'is_agreement_checked': self.is_agreement_checked,
                'agreement_image': self.agreement_image,
                'doctor_type': self.doctor_type,
                'is_merchant': self.is_merchant,
                'professional_certificate_num': self.professional_certificate_num,
            }
        else:
            return {
                'area_type': self.area_type,
                'address': self.address if self.area_type == DOCTOR_AREA_TYPE.ABROAD else
                (u'{}省 {}'.format(self.city.province.name, self.city.name) if self.city else ''),
                'user': self.person.user.last_name if self.person else '',
                'name': self.name,
                'portrait': self.portrait,
                'title': DOCTOR_TITLE_TYPE.getDesc(self.title),
                'title_type': self.title,
                'hospital': self.hospital,
                'login_phone': self.person.phone if self.person else '',
                'related_phone': self.phone,
                'assist_phone': self.assist_phone,
                'b_licences': self.b_licences,
                'p_licences': self.p_licences,
                'introduction': self.introduction,
                'good_at': self.good_at,
                'status': self.status,
                'business_partener': self.business_partener.id if self.business_partener else None,
                'business_group': self.business_group,
                'related_hospital': self.related_hospital.id if self.related_hospital else None,
                'is_agreement_checked': self.is_agreement_checked,
                'agreement_image': self.agreement_image,
                'hospital_type': HOSPITAL_TYPE.getDesc(self.hospital_type),
                'hospital_image': self.organization_images(),
                'doctor_type': self.doctor_type,
                'is_merchant': self.is_merchant
            }

    def create_doctor(self, user):
        """
        根据注册信息生成医生
        create by oldman at 2017-02-20
        :return: 医生实体
        """
        doctors = Doctor.objects.filter(user=self.person.user)
        if doctors.count() > 0:
            raise gen(CODES.USER_ALREADY_REIGST_DOCTOR)
        if self.doctor_type == DOCTOR_TYPE.OFFICER:
            doctor_hospital = Doctor.objects.filter(hospital_id=self.related_hospital.id,
                                                    doctor_type=DOCTOR_TYPE.OFFICER)
            if doctor_hospital.count() > 0:
                raise gen(CODES.HOSPITAL_HAD_OFFICER)
        # 每日回复限制，默认医生: 50, 机构管理者: 10
        reply_limit_map = {DOCTOR_TYPE.DOCTOR: 50, DOCTOR_TYPE.OFFICER: 10}
        doctor = Doctor.objects.create(
            user=self.person.user,
            name=self.name,
            portrait=self.portrait,
            doctor_type=self.doctor_type,
            phone=self.phone,
            assist_phone=self.assist_phone,
            title=self.title,
            department=self.department,
            introduction=self.introduction,
            area_type=self.area_type,
            good_at=self.good_at,
            business_partener_id=self.business_partener.id,
            business_group=self.business_group,
            hospital_id=self.related_hospital.id,
            accept_private_msg=False,
            is_online=False,
            # 注册通过合同待审状态
            status=DOCTOR_INFO_STATUS.CHECKED,
            is_merchant=self.is_merchant
        )
        doctor.reply_limit = reply_limit_map.get(doctor.doctor_type, 3)
        # doctor.update_licences_images(DOCTOR_LICENCE_TYPE.BUSINESS, self.b_licences)
        # doctor.update_licences_images(DOCTOR_LICENCE_TYPE.PRACTICE, self.p_licences)
        doctor.update_licence_images(self.b_licences, self.p_licences, self.t_licences)
        for part in doctor.good_at.split(','):
            try:
                body = BodyPart.objects.get(name=part)
                doctor.body_parts.add(body)
            except BodyPart.DoesNotExist:
                pass

        from maidan.models import MaidanSetting
        MaidanSetting.objects.create(
            doctor_id=doctor.id,
            is_open=True,
        )
        # 如果是机构管理者，同步医院图片
        if doctor.doctor_type == DOCTOR_TYPE.OFFICER:
            doctor.update_hospital_pics(self.hospital_pics())
        # 医生商务关联器
        docrecord = DocBusinessRecord()
        docrecord.doctor_id = doctor.id
        docrecord.to_business_id = doctor.business_partener.id
        docrecord.user = user
        docrecord.save()
        # 注册400电话
        doctor.register_phone_ext()
        # 同步医生信息到用户
        try:
            user_id = doctor.user.id
            user = get_user_by_id(user_id)
            extra = get_user_extra_by_user_id(user.id)
        except:
            user = None
            extra = None
        if extra and doctor.portrait:
            extra.portrait = doctor.portrait
            extra.last_login = datetime.datetime.now()
            extra.save()
        if doctor.name:
            name = doctor.name
            is_doctor = doctor.doctor_type == DOCTOR_TYPE.DOCTOR
            is_suozhang = doctor.user.id == 22
            if is_doctor and not is_suozhang:
                name = u'{} 医生'.format(name)
            user.last_name = name
            user.save()
        if self.merchant_id:
            doctor.allow_hospital_agent = True
        if self.is_merchant:
            doctor.become_merchant_time = datetime.datetime.now()
        doctor.save()
        # 更新doctorextra:
        from hippo.models import Doctor_Extra
        doctorExtra, _ = Doctor_Extra.objects.get_or_create(doctor_id=doctor.id)
        doctorExtra.professional_certificate_num = self.professional_certificate_num
        doctorExtra.save()
        return doctor

class RegisterOrganization(models.Model):
    class Meta:
        app_label = 'api'
        db_table = 'api_registerorganization_image'
        verbose_name = u'机构图片'
        verbose_name_plural = u'机构图片'

    image_url = models.CharField(max_length=256, help_text=u"图片url")
    doctor = models.ForeignKey(DoctorRegister, help_text=u"医生")

    @classmethod
    def edit_organization_image(cls, doctor_id, organization_images):
        # TODO Deprecated see doctorregister.update_hospital_pics()
        """
        修改注册机构的医院图片
        :param doctor_id: 注册医生id
        :param organization_images: 机构图片
        """
        if doctor_id is None or organization_images is None:
            return

        old_images = set(RegisterOrganization.objects.filter(doctor_id=doctor_id))
        new_images = set(RegisterOrganization.objects.get_or_create(doctor_id=doctor_id,
                                                                    image_url=item)[0] for item in
                         organization_images)
        for item in (old_images - new_images):
            item.delete()


class DoctorRegisterLicence(models.Model):
    class Meta:
        app_label = 'doctor'
        db_table = 'doctor_doctorregisterlicence'
        verbose_name = u'证书图片'
        verbose_name_plural = u'证书图片'

    doctor_register = models.ForeignKey(DoctorRegister, help_text=u"医生注册")
    type = models.IntegerField(verbose_name=u'证书类型', choices=DOCTOR_LICENCE_TYPE)
    image_url = ImgUrlField(img_type=IMG_TYPE.DOCTOR, max_length=256, help_text=u"图片url")


class DoctorRegisterAgreement(models.Model):
    class Meta:
        app_label = 'doctor'
        db_table = 'doctor_doctorregisteragreement'
        verbose_name = u'商务合同图片'
        verbose_name_plural = u'商务合同图片'

    doctor_register = models.ForeignKey(DoctorRegister, help_text=u"医生注册")
    image_url = ImgUrlField(img_type=IMG_TYPE.DOCTOR, max_length=256, help_text=u"图片url")


class DoctorRegisterRecord(models.Model):
    """
        每次都DoctorRegister的操作都会create一条新记录
    """
    class Meta:
        app_label = 'doctor'
        db_table = 'doctor_doctorregisterrecord'
        verbose_name = u'注册流程日志'
        verbose_name_plural = u'注册流程日志'

    doctor_register = models.ForeignKey(DoctorRegister, help_text=u"医生注册")
    status = models.IntegerField(
        verbose_name=u'注册状态', choices=DOCTOR_REGISTER_STATUS, default=DOCTOR_REGISTER_STATUS.DATA_SUBMITTED
    )
    reject_reason = models.CharField(u'拒绝原因', max_length=500, blank=True, null=True)
    handler = models.ForeignKey(Person, help_text=u"处理人", blank=True, null=True)
    created_at = models.DateTimeField(default=timezone.now, verbose_name=u'记录时间')
    content = models.TextField(u'修改内容')
    # 只有当驳回之后再次提交时，才存储改变的字段,  格式：[xxx, xxx]
    change_fields = models.CharField(verbose_name='改变的字段记录', max_length=500, null=True, blank=True)

    def get_detail_info(self):
        return {
            'reject_reason': self.reject_reason,
            'change_fields': self.change_fields
        }
