/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.security.trans.basic.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.security.trans.basic.dto.EmployeeDTO;
import org.security.ht.entity.basic.Department;
import org.security.ht.entity.basic.Employee;
import org.security.ht.entity.basic.Family;
import org.security.ht.entity.basic.JobRecord;
import org.security.trans.basic.service.IDepartmentService;
import org.security.trans.basic.service.IFamilyService;
import org.security.trans.basic.service.IJobRecordService;
import org.security.ht.vo.basic.EmployeeVO;
import org.security.trans.basic.mapper.EmployeeMapper;
import org.security.trans.basic.service.IEmployeeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.security.trans.common.service.IFileService;
import org.security.ht.vo.common.UploadVO;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.Func;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static org.security.common.Constant.*;

/**
 * 基础信息-员工 服务实现类
 *
 * @author BladeX
 * @since 2022-03-07
 */
@Service
@AllArgsConstructor
@Slf4j
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements IEmployeeService {
	private final IDepartmentService departmentService;
	private final IFamilyService familyService;
	private final IJobRecordService jobRecordService;
	private final IFileService fileService;

	@Override
	public IPage<EmployeeVO> selectEmployeePage(IPage<EmployeeDTO> page, EmployeeDTO employeeDTO) {
		String deptId = null;
		if (StringUtils.isNotBlank(employeeDTO.getDeptId())) {
			List<Long> deptIds = Func.toLongList(employeeDTO.getDeptId());
			deptId = String.valueOf(deptIds.get(deptIds.size() - 1));
		}
		Page<Employee> employeePage = new Page<>(page.getCurrent(), page.getSize());
		LambdaQueryWrapper<Employee> employeeQueryWrapper = setQueryWrappers(employeeDTO, deptId);
		IPage<Employee> resultPage = this.baseMapper.selectEmployeePage(employeePage, employeeQueryWrapper);
		List<Employee> employeeList = resultPage.getRecords();
		List<Employee> collect = employeeList.stream().filter(item -> Func.isNotEmpty(item.getDeptId())).collect(Collectors.toList());
		List<EmployeeVO> employeeVOList = new ArrayList<>();
		collect.forEach(emp -> setDataVO(employeeVOList, emp));
		return new Page<EmployeeVO>()
			.setRecords(employeeVOList)
			.setTotal(resultPage.getTotal())
			.setSize(resultPage.getSize())
			.setCurrent(resultPage.getCurrent());
	}


	/**
	 * 行内工龄筛选
	 */
	private List<EmployeeVO> screeningLengthOfService(EmployeeDTO employeeDTO, List<EmployeeVO> vos) {
		if (Func.isEmpty(employeeDTO.getProfessionalLengthOfService())){
			return vos;
		}
		//5年以下
		if (employeeDTO.getProfessionalLengthOfService() == 1){
			return vos.stream().filter(item -> item.getProfessionalLengthOfService() < 5).collect(Collectors.toList());
		}
		//[5-10)年
		if (employeeDTO.getProfessionalLengthOfService() == 2){
			return vos.stream().filter(item -> item.getProfessionalLengthOfService() >= 5 && item.getProfessionalLengthOfService() < 10).collect(Collectors.toList());
		}
		//[10-20}年
		if (employeeDTO.getProfessionalLengthOfService() == 3){
			return vos.stream().filter(item -> item.getProfessionalLengthOfService() >= 10 && item.getProfessionalLengthOfService() < 20).collect(Collectors.toList());
		}
		//[20-30)年
		if (employeeDTO.getProfessionalLengthOfService() == 4){
			return vos.stream().filter(item -> item.getProfessionalLengthOfService() >= 20 && item.getProfessionalLengthOfService() < 30).collect(Collectors.toList());
		}
		//30年及以上
		if (employeeDTO.getProfessionalLengthOfService() == 5){
			return vos.stream().filter(item -> item.getProfessionalLengthOfService() >= 30).collect(Collectors.toList());
		}
		return vos;
	}


	/**
	 * 企业工龄条件筛选
	 */
	private List<EmployeeVO> screeningEnterpriseSeniority(EmployeeDTO employeeDTO, List<EmployeeVO> vos) {
		if (Func.isEmpty(employeeDTO.getSeniorityInEnterprise())){
			return vos;
		}
		//5年以下
		if (employeeDTO.getSeniorityInEnterprise() == 1){
			return vos.stream().filter(item -> item.getSeniorityInEnterprise() < 5).collect(Collectors.toList());
		}
		//[5-10)年
		if (employeeDTO.getSeniorityInEnterprise() == 2){
			return vos.stream().filter(item -> item.getSeniorityInEnterprise() >= 5 && item.getSeniorityInEnterprise() < 10).collect(Collectors.toList());
		}
		//[10-20}年
		if (employeeDTO.getSeniorityInEnterprise() == 3){
			return vos.stream().filter(item -> item.getSeniorityInEnterprise() >= 10 && item.getSeniorityInEnterprise() < 20).collect(Collectors.toList());
		}
		//[20-30)年
		if (employeeDTO.getSeniorityInEnterprise() == 4){
			return vos.stream().filter(item -> item.getSeniorityInEnterprise() >= 20 && item.getSeniorityInEnterprise() < 30).collect(Collectors.toList());
		}
		//30年及以上
		if (employeeDTO.getSeniorityInEnterprise() == 5){
			return vos.stream().filter(item -> item.getSeniorityInEnterprise() >= 30).collect(Collectors.toList());
		}
		return vos;
	}

	private List<EmployeeVO> screeningAgeConditions(EmployeeDTO employeeDTO, List<EmployeeVO> employeeVOList) {
		//年龄段筛选条件为空
		if (Func.isEmpty(employeeDTO.getAgeGroup())){
			return employeeVOList;
		}
		//年龄段<20岁
		if (employeeDTO.getAgeGroup() == 1){
			return employeeVOList.stream().filter(item -> Integer.parseInt(item.getAge()) < 20).collect(Collectors.toList());
		}
		//[20-30)岁
		if (employeeDTO.getAgeGroup() == 2){
			return employeeVOList.stream().filter(item -> Integer.parseInt(item.getAge()) >= 20 && Integer.parseInt(item.getAge()) < 30).collect(Collectors.toList());
		}
		//[30-40}岁
		if (employeeDTO.getAgeGroup() == 3){
			return employeeVOList.stream().filter(item -> Integer.parseInt(item.getAge()) >= 30 && Integer.parseInt(item.getAge()) < 40).collect(Collectors.toList());
		}
		//[40-50)岁
		if (employeeDTO.getAgeGroup() == 4){
			return employeeVOList.stream().filter(item -> Integer.parseInt(item.getAge()) >= 40 && Integer.parseInt(item.getAge()) < 50).collect(Collectors.toList());
		}
		//50岁及以上
		if (employeeDTO.getAgeGroup() == 5){
			return employeeVOList.stream().filter(item -> Integer.parseInt(item.getAge()) >= 50).collect(Collectors.toList());
		}
		return employeeVOList;
	}

	/**
	 *构造查询条件
	 */
	private LambdaQueryWrapper<Employee> setQueryWrappers(EmployeeDTO employeeDTO, String deptId) {
		return new QueryWrapper<Employee>().lambda()
			.eq(Employee::getDelFlag,DELETE_FLAG_0)
			.eq(StringUtils.isNotBlank(deptId), Employee::getDeptId, deptId)
			.like(StringUtils.isNotBlank(employeeDTO.getName()), Employee::getName, employeeDTO.getName())
			.eq(StringUtils.isNotBlank(employeeDTO.getGender()), Employee::getGender, employeeDTO.getGender())
			.eq(StringUtils.isNotBlank(employeeDTO.getEmployeeNo()), Employee::getEmployeeNo, employeeDTO.getEmployeeNo())
			.eq(Func.isNoneBlank(employeeDTO.getEducation()),Employee:: getEducation, employeeDTO.getEducation())
			.eq(Func.isNoneBlank(employeeDTO.getPolitics()),Employee:: getPolitics, employeeDTO.getPolitics())
			.eq(Func.isNoneBlank(employeeDTO.getNation()),Employee:: getNation, employeeDTO.getNation())
			.eq(Func.isNoneBlank(employeeDTO.getCivilAirDefenseType()),Employee::getCivilAirDefenseType, employeeDTO.getCivilAirDefenseType());
	}

	/**
	 *给列表返回对象赋值
	 */
	private void setDataVO(List<EmployeeVO> employeeVOList, Employee emp) {
		Department department = departmentService.getOne(new QueryWrapper<Department>().lambda().eq(Func.isNotEmpty(emp.getDeptId()),Department::getId, emp.getDeptId()));
		EmployeeVO employeeVO = Func.copy(emp, EmployeeVO.class);
		employeeVO.setDepartment(department.getDeptName());
		setReturnCalculateValue(employeeVOList, emp, employeeVO);
	}

	/**
	 *给统计返回对象赋值
	 */
	private void setDataVO2(List<EmployeeVO> employeeVOList, Employee emp) {
		EmployeeVO employeeVO = Func.copy(emp, EmployeeVO.class);
		setReturnCalculateValue(employeeVOList, emp, employeeVO);
	}

	/**
	 * 计算值赋值
	 */
	private void setReturnCalculateValue(List<EmployeeVO> employeeVOList, Employee emp, EmployeeVO employeeVO) {
		String date = Func.formatDate(new Date()).substring(0,4);
		if(!Func.isNull(emp.getWorkBeginDate()) && Func.isNotBlank(emp.getWorkBeginDate())){
			//计算企业工龄
			employeeVO.setSeniorityInEnterprise(Integer.parseInt(date) - Integer.parseInt(emp.getWorkBeginDate().substring(0, 4)));
		}
		if(!Func.isNull(emp.getJobDate()) && Func.isNotBlank(emp.getJobDate())){
			//计算行业工龄
			employeeVO.setProfessionalLengthOfService(Integer.parseInt(date) - Integer.parseInt(emp.getJobDate().substring(0, 4)));
		}
		if(!Func.isNull(emp.getIdCard()) && Func.isNotBlank(emp.getIdCard()) && emp.getIdCard().trim().length()>=18){
			//计算年龄
			employeeVO.setAge(String.valueOf(Integer.parseInt(date) - Integer.parseInt(emp.getIdCard().trim().substring(6,10))));
		}
		employeeVOList.add(employeeVO);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean saveEmployeeAndFamiliesAndJobRecords(EmployeeDTO employeeDTO) {
		//根据身份证号判断系统是否已经存在该用户
		List<String> deptList = Func.toStrList(employeeDTO.getDeptId());
		employeeDTO.setDeptId(deptList.get(deptList.size()-1));
		QueryWrapper<Employee> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda().eq(Employee::getIdCard,employeeDTO.getIdCard());
		List<Employee> employeeList = this.list(queryWrapper);
		if (!employeeList.isEmpty()){
			return false;
		}
		//保存员工信息
		Employee employee = Func.copy(employeeDTO, Employee.class);
		List<Family> families = Func.copy(employeeDTO.getFamilies(), Family.class);
		List<JobRecord> jobRecords = Func.copy(employeeDTO.getJobRecords(), JobRecord.class);
		this.save(employee);
		//保存员工家庭成员信息
		families.forEach(family -> {
			assert employee != null;
			family.setEmployeeId(employee.getId());
		});
		//保存员工履历信息
		jobRecords.forEach(jobRecord -> {
			assert employee != null;
			jobRecord.setEmployeeId(employee.getId());
		});
		//保存相关附件信息
		fileService.saveAttachments(employeeDTO.getRelevantAttachments(),employee.getId());
		return familyService.saveBatch(families) && jobRecordService.saveBatch(jobRecords);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean removeEmployeeAndFamiliesAndJobRecords(List<Long> ids) {
		this.removeByIds(ids);
		ids.forEach(employeeId -> {
			String empId = String.valueOf(employeeId);
			familyService.remove(new QueryWrapper<Family>().lambda().eq(Family::getEmployeeId, empId));
			jobRecordService.remove(new QueryWrapper<JobRecord>().lambda().eq(JobRecord::getEmployeeId, empId));
		});
		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean updateEmployeeAndFamiliesAndJobRecords(EmployeeDTO employeeDTO) {
		List<String> deptList = Func.toStrList(employeeDTO.getDeptId());
		employeeDTO.setDeptId(deptList.get(deptList.size()-1));
		Employee employee = Func.copy(employeeDTO, Employee.class);
		this.updateById(employee);
		List<Family> families = Func.copy(employeeDTO.getFamilies(), Family.class);
		families.forEach(family->{
			family.setEmployeeId(employee.getId());
		});
		List<JobRecord> jobRecords = Func.copy(employeeDTO.getJobRecords(), JobRecord.class);
		jobRecords.forEach(jobRecord -> {
			jobRecord.setEmployeeId(employee.getId());
		});
		familyService.saveOrUpdateBatch(families);
		jobRecordService.saveOrUpdateBatch(jobRecords);
		//保存相关附件信息
		fileService.saveAttachments(employeeDTO.getRelevantAttachments(),employee.getId());
		//保存附件信息
		fileService.saveAttachments(employeeDTO.getIdCardFrontList(),employee.getId());
		//保存附件信息
		fileService.saveAttachments(employeeDTO.getIdCardBackList(),employee.getId());
		//保存附件信息
		fileService.saveAttachments(employeeDTO.getPicList(),employee.getId());
		return true;
	}

	@Override
	public EmployeeVO getEmployeeAndFamiliesAndJobRecords(String id) {
		Employee employee = this.getById(id);
		List<Family> familyList = familyService.list(new QueryWrapper<Family>().lambda()
			.eq(Family::getEmployeeId, id));
		List<JobRecord> jobRecordList = jobRecordService.list(new QueryWrapper<JobRecord>().lambda()
			.eq(JobRecord::getEmployeeId, id));

		Department department = departmentService.getById(employee.getDeptId());
		String ancestors = department.getAncestors();
		List<String> deptList = Func.toStrList(ancestors);
		List<String> list = deptList.stream().filter(item -> !item.equals(deptList.get(0))).collect(Collectors.toList());
		list.add(employee.getDeptId());
		//获取相关附件
		List<UploadVO> attachments = fileService.getAttachments(id,employee.getGroupName());
		//获取相关附件证件照
		List<UploadVO> attachmentsHead = fileService.getAttachments(id,employee.getGroupNameHead());
		//获取相关附件身份证正面
		List<UploadVO> attachmentsFront = fileService.getAttachments(id,employee.getGroupNameFront());
		//获取相关附件身份证反面
		List<UploadVO> attachmentsBack = fileService.getAttachments(id,employee.getGroupNameBack());
		EmployeeVO employeeVO = Func.copy(employee, EmployeeVO.class);
		assert employeeVO != null;
		employeeVO.setDeptList(list);
		employeeVO.setFamilies(familyList);
		employeeVO.setJobRecords(jobRecordList);
		employeeVO.setDepartment(department.getDeptName());
		employeeVO.setRelevantAttachments(attachments);
		employeeVO.setPicList(attachmentsHead);
		employeeVO.setIdCardFrontList(attachmentsFront);
		employeeVO.setIdCardBackList(attachmentsBack);
		return employeeVO;
	}

	@Override
	public EmployeeVO getLeaderByDeptId() {
		String deptId = AuthUtil.getDeptId();
		//获取登录账号机构以及上级机构所有领导
		Department department = departmentService.getById(deptId);
		String ancestors = department.getAncestors();
		List<String> deptList = Func.toStrList(ancestors);
		List<String> deptIds = deptList.stream().filter(item -> !item.equals(deptList.get(0))).collect(Collectors.toList());
		deptIds.add(deptId);
		List<Employee> allLeaders = this.list(new QueryWrapper<Employee>().lambda()
			.in(Employee::getDeptId, deptIds)
			.in(Employee::getCivilAirDefenseType, LEADER, LEADER_IN_CHARGE));
		List<Map<String, String>> leaderInChargeList = new ArrayList<>();
		allLeaders.forEach(leader -> {
			Map<String, String> map = new HashMap<>();
			map.put("key", leader.getId());
			map.put("value", leader.getName());
			leaderInChargeList.add(map);
		});
		//获取登录账号机构负责人
		List<Employee> Leaders = this.list(new QueryWrapper<Employee>().lambda()
			.eq(Employee::getDeptId, deptId)
			.eq(Employee::getCivilAirDefenseType, LEADER));
		List<Map<String, String>> leaderList = new ArrayList<>();
		Leaders.forEach(leader -> {
			Map<String, String> map = new HashMap<>();
			map.put("key", leader.getId());
			map.put("value", leader.getName());
			leaderList.add(map);
		});
		//获取登录账号机构安全员
		List<Employee> SafetyOfficers = this.list(new QueryWrapper<Employee>().lambda()
			.eq(Employee::getDeptId, deptId)
			.eq(Employee::getCivilAirDefenseType, SAFER));
		List<Map<String, String>> safetyOfficerList = new ArrayList<>();
		SafetyOfficers.forEach(safer -> {
			Map<String, String> map = new HashMap<>();
			map.put("key", safer.getId());
			map.put("value", safer.getName());
			safetyOfficerList.add(map);
		});
		EmployeeVO employeeVO = new EmployeeVO();
		employeeVO.setLeaderInChargeList(leaderInChargeList);
		employeeVO.setLeaderList(leaderList);
		employeeVO.setSafetyOfficerList(safetyOfficerList);
		return employeeVO;
	}

	@Override
	public boolean synEmployeeData(List<Employee> employees) {
		return this.saveOrUpdateBatch(employees);
	}

	@Override
	public List<EmployeeVO> getEmployeeStatisticsData(EmployeeDTO employeeDTO) {
		List<Employee> list = baseMapper.getEmployeeStatisticsData(employeeDTO);
		List<Employee> collect = list.stream().filter(item -> Func.isNotEmpty(item.getDeptId())).collect(Collectors.toList());
		List<EmployeeVO> employeeVOList = new ArrayList<>();
		collect.forEach(emp -> setDataVO2(employeeVOList, emp));
		return employeeVOList;
	}

}
