package com.patzn.lims.staff.service.impl;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.patzn.lims.common.DateUtils;
import com.patzn.lims.core.api.PtAssert;
import com.patzn.lims.core.web.Account;
import com.patzn.lims.core.web.LoginHelper;
import com.patzn.lims.core.web.BaseServiceImpl;
import com.patzn.lims.core.oss.OssClient;
import com.patzn.lims.core.oss.OssFileResult;
import com.patzn.lims.equip.dto.LmsEquipInfoDTO;
import com.patzn.lims.equip.service.ILmsEquipInfoService;
import com.patzn.lims.equip.vo.LmsEquipInfoVO;
import com.patzn.lims.excel.eto.LmsStaffETO;
import com.patzn.lims.staff.dto.LmsStaffInfoDTO;
import com.patzn.lims.staff.entity.*;
import com.patzn.lims.staff.mapper.LmsStaffInfoMapper;
import com.patzn.lims.staff.service.*;
import com.patzn.lims.staff.vo.LmsStaffInfoVO;
import com.patzn.lims.staff.vo.LmsStaffTrainRecordVO;
import com.patzn.lims.sys.entity.SysOrg;
import com.patzn.lims.sys.service.ISysOrgService;
import com.patzn.poibox.utils.ExcelUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.AmqpException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * <p>
 * 人员管理-人员基本信息 服务实现类
 * </p>
 *
 * @author patzn
 * @since 2017-11-03
 */
@Service
public class LmsStaffInfoServiceImpl extends BaseServiceImpl<LmsStaffInfoMapper, LmsStaffInfo> implements ILmsStaffInfoService {

    @Autowired
    private ILmsStaffRelOrgService lmsStaffRelOrgService;
    @Autowired
    private ILmsStaffLevelService lmsStaffLevelService;
    @Autowired
    private ISysOrgService orgClient;
    @Autowired
    private ILmsStaffProfessionalService lmsStaffProfessionalService;
    @Autowired
    private ILmsStaffEquipService lmsStaffEquipService;
    @Autowired
    private ILmsStaffScheduleService lmsStaffScheduleService;
    @Autowired
    private ILmsStaffStatusService lmsStaffStatusService;
    @Autowired
    private ILmsStaffTaskService lmsStaffTaskService;
    @Autowired
    private ILmsStaffFileService lmsStaffFileService;
    @Autowired
    private OssClient ossClient;
    @Autowired
    private ISysOrgService sysOrgClient;
    @Autowired
    private ILmsEquipInfoService lmsEquipInfoService;
//    @Autowired
//    private ILmsMsgService lmsMsgService;

    @Override
    public Page<LmsStaffInfoVO> pageVO(Page<LmsStaffInfoVO> page, LmsStaffInfoVO lmsStaffInfoVO) {
        lmsStaffInfoVO.setCompanyId(LoginHelper.getAccount().getCompanyId());
        return page.setRecords(baseMapper.selectPageVO(page, lmsStaffInfoVO));
    }


    @Override
    public List<LmsStaffInfoVO> listVO(LmsStaffInfoVO lmsStaffInfoVO) {
        lmsStaffInfoVO.setCompanyId(LoginHelper.getAccount().getCompanyId());
        return baseMapper.selectPageVO(lmsStaffInfoVO);
    }


    @Override
    public LmsStaffInfoVO getVOById(Long id) {
        LmsStaffInfoVO lmsStaffInfoVO = baseMapper.selectVOById(id);
        //文件集合，展示用
        List<LmsStaffFile> fileList = lmsStaffFileService.list(Wrappers.<LmsStaffFile>query().eq("rel_id", id));
        for (LmsStaffFile e:fileList) {
            e.setFileUrl(ossClient.getUrl(e.getFileUrl()).toString());
        }
        lmsStaffInfoVO.setFileList(fileList);
        //职称
        List<LmsStaffProfessional> list = lmsStaffProfessionalService.list(Wrappers.<LmsStaffProfessional>query().orderByAsc("start_date").eq("staff_id", lmsStaffInfoVO.getId()));
        if (list.size() > 0) {
            lmsStaffInfoVO.setProfess(list.get(0).getName());
        }
        return lmsStaffInfoVO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean edit(LmsStaffInfoDTO lmsStaffInfoDTO) {
        LmsStaffInfo staffInfo = getById(lmsStaffInfoDTO.getId());
        if (StringUtils.isNotBlank(lmsStaffInfoDTO.getNumber()) && StringUtils.isNotBlank(staffInfo.getNumber())) {
            PtAssert.fail(!lmsStaffInfoDTO.getNumber().equals(staffInfo.getNumber()) && checkExist(lmsStaffInfoDTO), "工号不可重复");
        }
        boolean result = updateById(lmsStaffInfoDTO);
        if (result && StringUtils.isNotBlank(lmsStaffInfoDTO.getOrgIds())) {
            lmsStaffRelOrgService.remove(Wrappers.<LmsStaffRelOrg>query().eq("staff_id", lmsStaffInfoDTO.getId()));
            addRelOrg(lmsStaffInfoDTO);
        }
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(LmsStaffInfoDTO lmsStaffInfoDTO) {
        LmsStaffInfo lmsStaffInfo = lmsStaffInfoDTO.convert(LmsStaffInfo.class);
        PtAssert.fail(checkExist(lmsStaffInfoDTO), "工号不可重复");
        boolean result = save(lmsStaffInfo);
        lmsStaffInfoDTO.setId(lmsStaffInfo.getId());
        if (result) {
            if (StringUtils.isNotBlank(lmsStaffInfoDTO.getOrgIds())) {
                addRelOrg(lmsStaffInfoDTO);
            }
        }
        //文件集合
        List<Long> list = lmsStaffInfoDTO.fileIdList();
        if (list != null) {
            lmsStaffFileService.updateFiles(list, lmsStaffInfo.getId());
        }
        return result;
    }

    private void addRelOrg(LmsStaffInfoDTO lmsStaffInfoDTO) {
        List<LmsStaffRelOrg> relList = Lists.newArrayList();
        for (Long orgId : lmsStaffInfoDTO.orgIdList()) {
            LmsStaffRelOrg rel = new LmsStaffRelOrg();
            rel.setOrgId(orgId);
            rel.setOrgName(orgClient.getById(orgId).getName());
            rel.setStaffId(lmsStaffInfoDTO.getId());
            relList.add(rel);
        }

        lmsStaffRelOrgService.saveBatch(relList);
    }

    private boolean checkExist(LmsStaffInfo lmsStaffInfo) {
        return baseMapper.selectCount(Wrappers.<LmsStaffInfo>query().eq("number", lmsStaffInfo.getNumber())) > 0;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean importItem(MultipartFile file) {
        Collection<LmsStaffETO> etos = ExcelUtils.readSheetAtOne(LmsStaffETO.class, file, "导入人员信息失败");
        if (CollectionUtils.isEmpty(etos)) {
            return false;
        }
        List<LmsStaffInfo> saveInforeList = new ArrayList<>();

        List<LmsStaffRelOrg> saveRelOrgList = new ArrayList<>();
        LmsStaffLevel level = new LmsStaffLevel();
        level.setCompanyId(LoginHelper.getAccount().getCompanyId());
        List<LmsStaffLevel> levelsList = lmsStaffLevelService.listAllRank(level);
        Map<String, LmsStaffLevel> levelMap = new HashMap<>();
        for (LmsStaffLevel rank : levelsList) {
            levelMap.put(rank.getName(), rank);
        }


        List<SysOrg> sysOrgList = orgClient.list(new SysOrg());
        Map<String, SysOrg> departMap = new HashMap<>();
        for (SysOrg org : sysOrgList) {
            departMap.put(org.getName(), org);
        }

        Set<String> numberSet = new HashSet<>();
        int i = 1;
        for (LmsStaffETO eto : etos) {
            PtAssert.fail(StringUtils.isBlank(eto.getName()), "请填写人员姓名！");
            PtAssert.fail(StringUtils.isBlank(eto.getNumber()), "请填写人员工号！");
            if (StringUtils.isNotBlank(eto.getRank())) {
                PtAssert.fail(null == levelMap.get(eto.getRank()), eto.getRank() + "人员等级不存在，请先去人员等级管理维护！");
            }
            if (StringUtils.isNotBlank(eto.getDepart())) {
                PtAssert.fail(null == departMap.get(eto.getDepart()), eto.getDepart() + "部门不存在，请先去系统管理维护部门！");
            }
            if (StringUtils.isNotBlank(eto.getNumber())) {
                numberSet.add(eto.getNumber());
            }
            PtAssert.fail(StringUtils.isNotBlank(eto.getEntryTime()) && !DateUtils.isValidDate(eto.getEntryTime(), "yyyy-MM-dd"), "第" + i + "入职时间请按照：2018-01-01的格式填写");
            PtAssert.fail(StringUtils.isNotBlank(eto.getExpireDate()) && !DateUtils.isValidDate(eto.getExpireDate(), "yyyy-MM-dd"), "第" + i + "行合同到期时间请按照：2018-01-01的格式填写");
            PtAssert.fail(StringUtils.isNotBlank(eto.getProbatioStartDate()) && !DateUtils.isValidDate(eto.getProbatioStartDate(), "yyyy-MM-dd"), "第" + i + "试用期开始日期请按照：2018-01-01的格式填写");
            PtAssert.fail(StringUtils.isNotBlank(eto.getProbatioEndDate()) && !DateUtils.isValidDate(eto.getProbatioEndDate(), "yyyy-MM-dd"), "第" + i + "试用期结束日期请按照：2018-01-01的格式填写");
            if (!StringUtils.isAnyBlank(eto.getProbatioStartDate(), eto.getProbatioEndDate())) {
                 if (DateUtils.toDate(eto.getProbatioEndDate()).before(DateUtils.toDate(eto.getProbatioStartDate()))){
                     PtAssert.fail("第" + i + "行数据,试用期结束时间必须比试用期开始时间大!");
                 }

            }
            i++;

        }

        PtAssert.fail(numberSet.size() != etos.size(), "待导入的人员工号不能重复！");
        int count = super.count(Wrappers.<LmsStaffInfo>query().in("number", numberSet));
        PtAssert.fail(count > 0, "待导入人员不能与系统中人员工号重复！");

        for (LmsStaffETO eto : etos) {
            LmsStaffInfo info = new LmsStaffInfo();
            info.setId(IdWorker.getId());
            info.setName(eto.getName());
            if (null != levelMap.get(eto.getRank())) {
                info.setLevelId(levelMap.get(eto.getRank()).getId());
            }
            if (null != departMap.get(eto.getDepart())) {
                LmsStaffRelOrg org = new LmsStaffRelOrg();
                org.setOrgId(departMap.get(eto.getDepart()).getId());
                org.setOrgName(departMap.get(eto.getDepart()).getName());
                org.setStaffId(info.getId());
                saveRelOrgList.add(org);
            }
            info.setNumber(eto.getNumber());
            info.setRemark(eto.getRemark());

            //新添加的内容
            info.setAge(eto.getAge());
            //日期
            if (StringUtils.isNotBlank(eto.getEntryTime())) {
                PtAssert.fail(!judgeDate(eto.getEntryTime()), "入职时间格式错误！");
                info.setEntryTime(DateUtils.toDate(eto.getEntryTime()));
            }
            if (StringUtils.isNotBlank(eto.getWorkTime())) {
                PtAssert.fail(!judgeDate(eto.getWorkTime()), "参加工作时间格式错误！");
                info.setWorkTime(DateUtils.toDate(eto.getWorkTime()));
            }
            if (StringUtils.isNotBlank(eto.getGraduationTime())) {
                PtAssert.fail(!judgeDate(eto.getGraduationTime()), "毕业时间格式错误！");
                info.setGraduationTime(DateUtils.toDate(eto.getGraduationTime()));
            }
            info.setProfession(eto.getProfession());
            info.setEducation(eto.getEducation());
            info.setGraduatedSchool(eto.getGraduatedSchool());
            info.setPost(eto.getPost());
            if (StringUtils.isNotBlank(eto.getProbatioStartDate())) {
                info.setProbatioStartDate(DateUtils.toDate(eto.getProbatioStartDate()));
            }
            if (StringUtils.isNotBlank(eto.getProbatioEndDate())) {
                info.setProbatioEndDate(DateUtils.toDate(eto.getProbatioEndDate()));
            }
            if (StringUtils.isNotBlank(eto.getExpireDate())) {
                info.setExpireDate(DateUtils.toDate(eto.getExpireDate()));
            }
            if ("在岗".equals(eto.getStatus())) {
                info.setStatus(1);
            } else if ("离职".equals(eto.getStatus())) {
                info.setStatus(0);
            } else {
                info.setStatus(1);
            }
            if ("男".equals(eto.getSex())) {
                info.setSex(1);
            } else if ("女".equals(eto.getSex())) {
                info.setSex(2);
            }
            if ("是".equals(eto.getIfAuditor())) {
                info.setIfAuditor(1);
            } else if ("否".equals(eto.getIfAuditor())) {
                info.setIfAuditor(0);
            }
            if (!StringUtils.isAnyBlank(eto.getProbatioStartDate(), eto.getProbatioEndDate(), eto.getEntryTime())) {
                int days = DateUtils.differentDays(DateUtils.toDate(eto.getProbatioStartDate()), DateUtils.toDate(eto.getProbatioEndDate()));
               try {
                  info.setBecomeDate(com.patzn.lims.common.DateUtils.plusDay(days, eto.getEntryTime()));
              } catch (ParseException e) {
                  e.printStackTrace();
            }
            }
            saveInforeList.add(info);
        }
        if (saveRelOrgList.size() > 0) {
            return super.saveBatch(saveInforeList) && lmsStaffRelOrgService.saveBatch(saveRelOrgList);
        } else {
            return super.saveBatch(saveInforeList);
        }
    }


    @Override
    public boolean removeAllRel(Long[] ids) {
        if (null != ids && ids.length > 0) {
            lmsStaffEquipService.remove(Wrappers.<LmsStaffEquip>query().in("staff_id", ids));
            lmsStaffScheduleService.remove(Wrappers.<LmsStaffSchedule>query().in("staff_id", ids));
            lmsStaffStatusService.remove(Wrappers.<LmsStaffStatus>query().in("staff_id", ids));
            lmsStaffTaskService.remove(Wrappers.<LmsStaffTask>query().in("staff_id", ids));
            lmsStaffProfessionalService.remove(Wrappers.<LmsStaffProfessional>query().in("staff_id", ids));
            lmsStaffRelOrgService.remove(Wrappers.<LmsStaffRelOrg>query().in("staff_id", ids));
            //删除附件
            lmsStaffFileService.remove(Wrappers.<LmsStaffFile>query().in("rel_id", ids));
            baseMapper.delete(Wrappers.<LmsStaffInfo>query().in("id", ids));
        }
        return true;
    }

    @Override
    public LmsStaffFile uploadFile(MultipartFile file, Long id, Integer type) {
        OssFileResult ossFileResult = ossClient.upload(file);
        if (null == ossFileResult) {
            return null;
        }
        LmsStaffFile lmsStaffFile = new LmsStaffFile();
        lmsStaffFile.setFileOrginName(file.getOriginalFilename());
        lmsStaffFile.setFileUrl(ossFileResult.getObjectKey());
        lmsStaffFile.setType(type);
        lmsStaffFile.setCompanyId(LoginHelper.getAccount().getCompanyId());
        if (id != 0) {
            lmsStaffFile.setRelId(id);
        }
        lmsStaffFileService.save(lmsStaffFile);
        //回显数据
        lmsStaffFile.setFileUrl(ossClient.getUrl(ossFileResult.getObjectKey()).toString());
//        lmsStaffFile.setFileUrl(ossFileResult.getObjectKey());
        return lmsStaffFile;
    }

    @Override
    public Boolean deleteFile(Long id) {
        try {
            LmsStaffFile lmsStaffFile = lmsStaffFileService.getById(id);
            ossClient.deleteObject(lmsStaffFile.getFileUrl());
            lmsStaffFileService.removeById(id);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    @Override
    public LmsStaffInfoVO temp() {
        LmsStaffInfoVO lmsStaffInfoVO = new LmsStaffInfoVO();
        List<LmsStaffFile> list = new ArrayList<>();
        LmsStaffInfo lmsStaffInfo = this.getOne(Wrappers.<LmsStaffInfo>query().eq("temp_status", 0));
        if (lmsStaffInfo == null) {
            LmsStaffInfo info = new LmsStaffInfo();
            this.save(info);
            lmsStaffInfoVO.setId(info.getId());
            lmsStaffInfoVO.setFileList(list);
            return lmsStaffInfoVO;
        } else {
            list = lmsStaffFileService.list(Wrappers.<LmsStaffFile>query().eq("rel_id", lmsStaffInfo.getId()));
            lmsStaffInfoVO.setId(lmsStaffInfo.getId());
            lmsStaffInfoVO.setFileList(list);
            return lmsStaffInfoVO;
        }
    }

    @Override
    public Page<LmsStaffInfoVO> getListByOrg(Page<LmsStaffInfoVO> page, LmsStaffInfoVO lmsStaffInfo) {
        SysOrg sysOrg = new SysOrg();
        sysOrg.setId(lmsStaffInfo.getOrgId());
        List<SysOrg> list = sysOrgClient.list(sysOrg);
        List<Long> ids = list.stream().map(e -> e.getId()).collect(Collectors.toList());
        return page.setRecords(baseMapper.getInfoByOrg(page, ids, lmsStaffInfo));
    }

    @Override
    public Page<LmsStaffTrainRecordVO> getEduList(Page<LmsStaffTrainRecordVO> page, LmsStaffTrainRecordVO lmsStaffTrainRecordVO) {
        return page.setRecords(baseMapper.getEduList(page, lmsStaffTrainRecordVO));
    }

    @Override
    public Page<LmsEquipInfoVO> pageEq(Page<LmsEquipInfoVO> page, LmsEquipInfoDTO lmsEquipInfoDTO) {
        return page.setRecords(baseMapper.selectPageEquip(page, LoginHelper.getAccount(), lmsEquipInfoDTO));
    }

    @Override
    public List<LmsStaffInfoVO> getStaffList(LmsStaffInfoVO lmsStaffInfo) {
        SysOrg sysOrg = new SysOrg();
        sysOrg.setId(lmsStaffInfo.getOrgId());
        List<SysOrg> list = sysOrgClient.list(sysOrg);
        List<Long> ids = list.stream().map(e -> e.getId()).collect(Collectors.toList());
        return baseMapper.getStaffList(ids, lmsStaffInfo);
    }

    @Override
    public void lmsStaffInfoExpireMsg() {
        List<LmsStaffInfo> list = baseMapper.selectListExpire();
        if (CollectionUtils.isNotEmpty(list)) {
            for (LmsStaffInfo info : list) {
                if (StringUtils.isNotBlank(info.getName())) {
                    sendMsg(info, "员工合同到期提醒", info.getName() + "的合同到期提醒,到期时间" + DateUtils.toYearMonthDay(info.getExpireDate()));
                }
            }
        }
    }

    @Override
    public void lmsStaffInfoBecomeMsg() {
        List<LmsStaffInfo> list = baseMapper.selectBecomeMsg();
        if (CollectionUtils.isNotEmpty(list)) {
            for (LmsStaffInfo info : list) {
                if (StringUtils.isNotBlank(info.getName())) {
                    sendMsg(info, "员工入职转正提醒", info.getName() + "的入职转正提醒,转正时间" + DateUtils.toYearMonthDay(info.getBecomeDate()));
                }

            }
        }
    }

    /**
     * 消息通知
     *
     * @param lmsStaffTrainPlan
     */
    private void sendMsg(LmsStaffInfo info, String title, String content) {
        try {

            Long userId = null;
            if (null != info.getUid()) {
                userId = info.getUid();
            } else if (null != info.getLid()) {
                userId = info.getLid();
            }
            if (null != userId) {
                StringBuilder contents = new StringBuilder();
                if (StringUtils.isNotEmpty(info.getNumber())) {
                    contents.append("工号").append(info.getNumber());
                }
                if (StringUtils.isNotBlank(info.getName())) {
                    contents.append("姓名：").append(info.getName());
                }
                contents.append(content);
                Account account = new Account();
                account.setCompanyId(info.getCompanyId());
                account.setUserId(0L);
                account.setUserName("系统消息");
//                lmsMsgService.sendMsg("/lims/staff_info", contents.toString(),
//                        title, account, Arrays.asList(userId));
            }


        } catch (AmqpException e) {
            log.error("人员合同消息发送失败"+ e.getMessage());
        }
    }

    public Boolean judgeDate(String date) {
        String regex = "[0-9]{4}-[0-9]{2}-[0-9]{2}";
        Pattern pattern = Pattern.compile(regex);
        Matcher m = pattern.matcher(date);
        boolean dateFlag = m.matches();
        if (!dateFlag) {
            return false;
        }
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        formatter.setLenient(false);
        try {
            formatter.parse(date);
            return true;
        } catch (Exception e) {
            return false;
        }
    }


}

