
from apps.hrm.models import Certificate, Employee
from apps.hrm.services import HrmService
from apps.system.models import Post, User, UserPost
from apps.utils.sms import send_sms
from apps.utils.tools import get_info_from_id, ranstr
from apps.wf.models import Ticket, Transition
from apps.rpm.models import Remployee, Rfile, Rparty, Rpj, Rpjcertificate, Rpjfile, Rpjmember
from django.contrib.auth.hashers import make_password
from rest_framework.exceptions import ParseError
from dateutil import tz
from django.utils import timezone
from datetime import datetime, timedelta
from django.db.models import Max, Min
from server.settings import get_sysconfig


def sync_to_rep(ep: Employee):
    # 个人信息完善时同步到rep表
    Remployee.objects.filter(employee=ep).update(
        name=ep.name, phone=ep.phone, id_number=ep.id_number, photo=ep.photo)
    if ep.user:
        rps = Rparty.objects.filter(admin=ep.user)
        # 如果是管理员账户
        for i in rps:
            Remployee.objects.get_or_create(employee=ep, defaults={
                'employee': ep,
                'name': ep.name,
                'phone': ep.phone,
                'id_number': ep.id_number,
                'photo': ep.photo,
                'rparty': i
            })


def bind_rpj(ticket: Ticket, transition: Transition, new_ticket_data: dict):
    rpj = Rpj.objects.get(id=new_ticket_data['rpj'])
    if rpj.ticket and rpj.ticket.id != ticket.id:
        raise ParseError('重复创建工单')
    if not Rpjmember.objects.filter(rpj=rpj).exists():
        raise ParseError('请至少选择一位入厂人员')
    ticket_data = ticket.ticket_data
    ticket_data.update(
        {'belong_dept': rpj.belong_dept.id if rpj.belong_dept else '0'})
    ticket.ticket_data = ticket_data
    ticket.belong_dept = rpj.belong_dept
    ticket.create_by = rpj.create_by
    ticket.save()
    if rpj.ticket is None:
        rpj.ticket = ticket
        rpj.state = Rpj.RPJ_AUDIT
        rpj.save()


def rpj_member_leave(i: Rpjmember):
    """人员离开项目
    """
    rpj = i.rpj
    rep = i.remployee
    ep = rep.employee

    # 查找本人除此之外还在的项目
    rpj_qs = Rpj.objects.filter(remployees=rep, state__in=[
                                Rpj.RPJ_WORKING, Rpj.RPJ_ENTER]).exclude(id=rpj.id)
    if rpj_qs.exists():
        leave_time__max = rpj_qs.aggregate(Max('leave_time'))[
            'leave_time__max']
        come_time_min = rpj_qs.aggregate(Min('come_time'))['come_time__min']
        rpj_ = rpj_qs.order_by('-create_time').first()
        rep.rpj = rpj_  # 更新当前入厂项目
        rep.save()
        rpj_dept = rpj_.rparty.dept
        if ep:
            ep.belong_dept = rpj_dept
            ep.save()
            if ep.user:
                ep.user.belong_dept = rpj_dept
                ep.user.save()
        # 同步至大华人员库并下发人脸
        HrmService.sync_dahua_employee(
            ep, ep.photo, come_time_min, leave_time__max)
    else:
        if ep:
            ep.job_state = Employee.JOB_OFF
            ep.save()
            HrmService.sync_dahua_employee(
                ep, ep.photo, rpj.come_time, timezone.now() + timedelta(hours=8))
            if ep.user:
                ep.user.is_deleted = True
                ep.user.save()


def rpj_member_come(i: Rpjmember):
    """人员入厂
    """
    # tzinfo = tz.gettz('Asia/Shanghai')
    rep = i.remployee
    rpj = i.rpj
    rpj_dept = rpj.rparty.dept
    post = Post.objects.get(code='remployee')
    # 尝试找到人员
    ep = Employee.objects.get_queryset(all=True).filter(
        id_number=rep.id_number).first()
    ep2 = Employee.objects.get_queryset(
        all=True).filter(phone=rep.phone).first()
    if ep:
        pass
    elif ep2:
        ep = ep2
    else:
        ep = Employee()
        ep.id_number = rep.id_number

    ep.name = rep.name
    ep.id_number = rep.id_number
    ep.gender = get_info_from_id(rep.id_number).get('gender', '男')
    ep.phone = rep.phone
    old_photo = ep.photo
    ep.photo = rep.photo
    ep.job_state = Employee.JOB_ON
    ep.type = 'remployee'
    ep.belong_dept = rpj_dept
    ep.is_deleted = False
    ep.job_state = 10
    ep.save()
    # 给相关方人员创建账户
    user_e = ep.user
    if user_e:  # 如果该人员有账户
        user_e.is_active = True
        user_e.is_deleted = False
        user_e.save()
    else:
        user_e = User.objects.get_queryset(all=True).filter(
            phone=rep.phone).first()  # 看看有没有存在的账户
        if user_e:
            user_e.is_deleted = False
        else:
            user_e = User()
            user_e.username = 'RE_' + ranstr(6)
            user_e.password = make_password(get_sysconfig("default_pwd", "abc!0000"))
        user_e.name = rep.name
        user_e.phone = rep.phone
        user_e.type = 'remployee'
        user_e.belong_dept = rpj_dept
        user_e.post = post
        user_e.save()
    # 账号划给部门
    UserPost.objects.get_or_create(user=user_e, dept=rpj_dept,
                                   defaults={
                                       'user': user_e,
                                       'dept': rpj_dept,
                                       'post': post
                                   })
    ep.user = user_e
    ep.save()
    # 回写
    rep.employee = ep
    rep.rpj = rpj  # 更新当前入厂项目
    rep.save()

    # come_time = rpj.come_time
    # leave_time = rpj.leave_time
    # dh_face_card_start = ep.third_info.get('dh_face_card_start', None)
    # dh_face_card_end = ep.third_info.get('dh_face_card_end', None)
    # if dh_face_card_start:
    #     dh_face_card_start = datetime.strptime(dh_face_card_start, "%Y-%m-%d %H:%M:%S").replace(tzinfo=tzinfo)
    #     if dh_face_card_start < come_time:
    #         come_time = dh_face_card_start
    # if dh_face_card_end:
    #     dh_face_card_end = datetime.strptime(dh_face_card_end, "%Y-%m-%d %H:%M:%S").replace(tzinfo=tzinfo)
    #     if dh_face_card_end > leave_time:
    #         leave_time = dh_face_card_end
    rpj_qs = Rpj.objects.filter(remployees=rep, state__in=[
                                Rpj.RPJ_WORKING, Rpj.RPJ_ENTER]) | Rpj.objects.filter(id=rpj.id)
    leave_time__max = rpj_qs.aggregate(Max('leave_time'))['leave_time__max']
    come_time__min = rpj_qs.aggregate(Min('come_time'))['come_time__min']
    # 同步至大华人员库并下发人脸
    HrmService.sync_dahua_employee(
        ep, old_photo, come_time__min, leave_time__max)


def rpj_certificate_in(rpjm: Rpjmember):
    for i in Rpjcertificate.objects.filter(rpj_member=rpjm):
        ct = Certificate.objects.filter(number=i.number, name=i.name).first()
        if ct:
            pass
        else:
            ct = Certificate()
            ctm = i.rpj_member.remployee.employee
            if ctm:
                ct.employee = ctm
        ct.name = i.name
        ct.number = i.number
        ct.type = i.type
        ct.issue_date = i.issue_date
        ct.expiration_date = i.expiration_date
        ct.review_date = i.review_date
        ct.file = i.file
        ct.state = ct.get_state()
        ct.save()


def rpj_audit_end(ticket):
    rpj = Rpj.objects.get(ticket=ticket)
    # 更新入厂项目人员库
    for i in Rpjmember.objects.filter(rpj=rpj):
        rpj_member_come(i)
    # 更新入厂项目人员证书库
    for i in Rpjcertificate.objects.filter(rpj_member__rpj=rpj):
        ct = Certificate.objects.filter(number=i.number, name=i.name).first()
        if ct:
            pass
        else:
            ct = Certificate()
            ct.employee = i.rpj_member.remployee.employee
        ct.name = i.name
        ct.number = i.number
        ct.type = i.type
        ct.issue_date = i.issue_date
        ct.expiration_date = i.expiration_date
        ct.review_date = i.review_date
        ct.file = i.file
        ct.state = ct.get_state()
        ct.save()
    # 更新相关方资料库后续可从资料库里选择
    for i in Rpjfile.objects.filter(rpj=rpj):
        rf = Rfile.objects.filter(
            file_cate=i.file_cate, rparty=i.rpj.rparty).first()
        if rf:
            pass
        else:
            rf = Rfile()
            rf.rparty = i.rpj.rparty
            rf.file_cate = i.file_cate
            rf.belong_dept = i.rpj.rparty.dept
        rf.save()
        for m in i.files.all():
            rf.files.add(m)
    rpj.state = Rpj.RPJ_ENTER
    rpj.save()
    # 发送通知?
    phone = rpj.create_by.phone if rpj.create_by else None
    if phone:
        send_sms(phone=phone, template_code=1004,
                 template_param={'name': '相关方项目'})
