package cn.lihongjie.coal.employee.entity;

import cn.lihongjie.coal.base.entity.OrgCommonEntity;
import cn.lihongjie.coal.common.IdCardUtils;
import cn.lihongjie.coal.department.entity.DepartmentEntity;
import cn.lihongjie.coal.exception.BizException;
import cn.lihongjie.coal.file.entity.FileEntity;
import cn.lihongjie.coal.jobPost.entity.JobPostEntity;

import jakarta.persistence.*;

import lombok.Data;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.Comment;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;

@Data
@Entity

@jakarta.persistence.Table(indexes = @jakarta.persistence.Index(name ="idx_employee_org_id", columnList = "organization_id"))

public class EmployeeEntity extends OrgCommonEntity {

    @Comment("性别")
    private String sex;

    @Comment("政治面貌")
    private String politicalStatus;


    @Comment("民族")
    private String nation;

    @Comment("婚姻状况")
    private String marriage;

    @Comment("入职时间")
    private LocalDate entryDate;

    @Comment("离职时间")
    private LocalDate resignDate;

    @Comment("离职原因")
    private String resignReason;

    @Comment("身份证号")
    private String idCard;

    @Comment("学历")
    private String education;

    @Comment("毕业学校")
    private String school;

    @Comment("籍贯")
    private String nativePlace;

    @Comment("住址")
    private String address;

    @Comment("手机号")
    private String phone;

    @ManyToOne(fetch = FetchType.LAZY)
    private FileEntity headImage;

    @Comment("身份证照片")
    @OneToMany
    @Fetch(FetchMode.SUBSELECT)
    private List<FileEntity> idImages;

    @Comment("银行卡照片")
    @OneToMany
    @Fetch(FetchMode.SUBSELECT)
    private List<FileEntity> bankCardImages;

    @Comment("部门")
    @ManyToOne(fetch = FetchType.LAZY)
    private DepartmentEntity department;

    @Comment("岗位")
    @ManyToOne(fetch = FetchType.LAZY)
    private JobPostEntity jobPost;

    @Comment("银行编码")
    private String bank;

    @Comment("银行卡号")
    private String bankCardNumber;

    @Comment("收款人姓名")
    private String bankCardName;

    @Comment("员工状态")
    private String empStatus;

    @ElementCollection
    @Fetch(FetchMode.SUBSELECT)
    private List<EmpFamilyMemberVO> familyMembers;

    @ElementCollection
    @Fetch(FetchMode.SUBSELECT)
    private List<EmpCertVO> certs;

    @ElementCollection
    @Fetch(FetchMode.SUBSELECT)
    private List<EmpCarVO> cars;



    @ElementCollection
    @Fetch(FetchMode.SUBSELECT)
    private List<EmpWorkRecordVO> workRecords;

    /**
     * “五险”讲的是五种保险，包括养老保险、医疗保险、失业保险、工伤保险和生育保险。
     *
     * <p>“一金”指的是住房公积金。
     *
     * <p>其中养老保险、医疗保险和失业保险，这三种险是由企业和个人共同缴纳的保费，工伤保险和生育保险完全是由企业承担的。个人不需要缴纳。这里要注意的是“五险”是法定的，而“一金”不是法定的。
     */
    @Comment("养老保险基数")
    private Double insurance1Base;

    @Comment("养老保险比例")
    private Double insurance1Percent;

    @Comment("医疗保险基数")
    private Double insurance2Base;

    @Comment("医疗保险比例")
    private Double insurance2Percent;

    @Comment("失业保险基数")
    private Double insurance3Base;

    @Comment("失业保险比例")
    private Double insurance3Percent;

    @Comment("工伤保险基数")
    private Double insurance4Base;

    @Comment("工伤保险比例")
    private Double insurance4Percent;

    @Comment("生育保险基数")
    private Double insurance5Base;

    @Comment("生育保险比例")
    private Double insurance5Percent;

    @Comment("住房公积金基数")
    private Double insurance6Base;

    @Comment("住房公积金比例")
    private Double insurance6Percent;

    @Comment("工龄")
    private Double workAge;

    @Comment("年龄")
    private Double age;

    @Comment("出生日期")
    private LocalDate birthday;

    @Comment("身份证签发机关")
    private String issueAuthority;

    @Comment("有效期限")
    private LocalDate validPeriod;

    @Comment("是否永久有效")
    private Boolean permanent;


    @Override
    public void prePersist() {
        super.prePersist();

        updateCommon();
    }

    private void updateCommon() {

        if (StringUtils.equalsAny(empStatus, "0")) {

            workAge = null;

        } else if (StringUtils.equalsAny(empStatus, "1")) {

            if (this.entryDate == null) {
                throw new BizException(this.getName() + " 入职时间不能为空");
            }

            long monthDiff = ChronoUnit.MONTHS.between(entryDate, LocalDate.now());

            if (monthDiff < 0) {
                throw new BizException(this.getName() + " 入职时间不能大于当前时间");
            }

            this.workAge =
                    BigDecimal.valueOf(monthDiff)
                            .divide(BigDecimal.valueOf(12), 1, RoundingMode.FLOOR)
                            .doubleValue();

        } else if (StringUtils.equalsAny(empStatus, "2")) {

            if (this.resignDate == null) {
                throw new BizException(this.getName() + " 离职时间不能为空");
            }

            if (this.entryDate == null) {
                throw new BizException(this.getName() + " 入职时间不能为空");
            }

            long monthDiff = ChronoUnit.MONTHS.between(entryDate, resignDate);

            if (monthDiff < 0) {
                throw new BizException(this.getName() + " 离职时间不能小于入职时间");
            }

            this.workAge =
                    BigDecimal.valueOf(monthDiff)
                            .divide(BigDecimal.valueOf(12), 1, RoundingMode.FLOOR)
                            .doubleValue();

        } else {

            throw new BizException(this.getName() + " 员工状态不合法 " + empStatus);
        }

        if (StringUtils.isNotEmpty(idCard)) {

            if (IdCardUtils.validateCard(idCard)) {

                this.birthday =
                        LocalDate.parse(
                                IdCardUtils.getBirthByIdCard(idCard),
                                DateTimeFormatter.ofPattern("yyyyMMdd"));

                this.age =
                        BigDecimal.valueOf(ChronoUnit.YEARS.between(birthday, LocalDate.now()))
                                .doubleValue();
            } else {
                throw new BizException(this.getName() + " 身份证号不合法");
            }
        }
    }

    @Override
    public void preUpdate() {
        super.preUpdate();
        updateCommon();
    }
}