package com.lz.modules.sys.service.app.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lz.common.utils.BigDecimalUtil;
import com.lz.common.utils.Constant;
import com.lz.modules.app.entity.StaffEntity;
import com.lz.modules.app.resp.ResultDetailResp;
import com.lz.modules.app.resp.Step;
import com.lz.modules.app.service.DepartmentsService;
import com.lz.modules.app.service.StaffService;
import com.lz.modules.app.utils.t.TwoTuple;
import com.lz.modules.flow.entity.*;
import com.lz.modules.flow.model.Auth;
import com.lz.modules.flow.model.ResultDetailDto;
import com.lz.modules.flow.model.StaffRoleDto;
import com.lz.modules.flow.service.*;
import com.lz.modules.sys.dao.app.ResultDetailMapper;
import com.lz.modules.sys.entity.app.ResultDetail;
import com.lz.modules.sys.entity.app.ResultRecord;
import com.lz.modules.sys.service.app.ResultDetailService;
import com.lz.modules.sys.service.app.ResultRecordService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
* <p>
* 业绩详情表 服务类
* </p>
*
* @author quyixiao
* @since 2020-08-10
*/

@Service
@Slf4j
public class ResultDetailServiceImpl extends ServiceImpl<ResultDetailMapper, ResultDetail> implements ResultDetailService {


	@Autowired
	private ResultDetailMapper resultDetailMapper;

	@Autowired
	private StaffService staffService;

	@Autowired
	private ResultRecordService resultRecordService;

	@Autowired
	private FlowRelationService flowRelationService;

	@Autowired
	private StaffRoleService staffRoleService;


	@Override
	public ResultDetail selectResultDetailById(Long id){
		return resultDetailMapper.selectResultDetailById(id);
	}


	@Autowired
	private StaffRoleDepartmentService staffRoleDepartmentService;

	@Autowired
	private DepartmentsService departmentsService;

	@Autowired
	private FlowService flowService;

	@Autowired
	private FlowRecordService flowRecordService;


	static int maxInsertSQL = 100;

	@Override
	public Long insertResultDetail(ResultDetail resultDetail){
		return resultDetailMapper.insertResultDetail(resultDetail);
	}



	@Override
	public int updateResultDetailById(ResultDetail resultDetail){
		return resultDetailMapper.updateResultDetailById(resultDetail);
	}



	@Override
	public int updateCoverResultDetailById(ResultDetail resultDetail){
		return resultDetailMapper.updateCoverResultDetailById(resultDetail);
	}



	@Override
	public int deleteResultDetailById(Long id){
		return resultDetailMapper.deleteResultDetailById(id);
	}


    @Override
    public List<ResultDetail> selectByRecordId(Long recordResultId) {
        return resultDetailMapper.selectByRecordId(recordResultId);
    }

	@Override
	public List<ResultDetail> selectByRecordIdType(Long recordResultId, Integer type) {
		return resultDetailMapper.selectByRecordIdType(recordResultId,type);
	}

	public ResultDetailResp getYeJi() {
		ResultDetailResp result = new ResultDetailResp();
		result.setCheckRange("绩效");
		result.setCheckWeight(new BigDecimal(0.7));
		result.setIsAdd(1);
		result.setIsEdit(1);
		result.setType(1);
		return result;
	}

	public ResultDetailResp getYeJiKaoHe(BigDecimal acquireScore) {
		ResultDetailResp respHeader = new ResultDetailResp();
		respHeader.setKeyResult("绩效考核结果");
		respHeader.setCheckWeight(new BigDecimal(0.7));
		respHeader.setSuperScore("/");
		respHeader.setAcquireScore(acquireScore);
		respHeader.setScoreComment("/");
		respHeader.setIsAdd(-1);
		return respHeader;
	}

	public ResultDetailResp getWenHuaJiaZhiGua1(Auth auth) {
		ResultDetailResp wenhua1 = new ResultDetailResp();
		wenhua1.setCheckRange("文化价值观");
		wenhua1.setTarget("做人：相信、包容、担当\n 做事：用户第一、求真、极致");
		wenhua1.setType(2);
		wenhua1.setIsEdit(auth.getWenHuaEdit());
		wenhua1.setCheckWeight(new BigDecimal(0.3));
		return wenhua1;
	}

	public ResultDetailResp getWenHuaJiaZhiGua2(Auth auth) {
		ResultDetailResp wenhua2 = new ResultDetailResp();
		wenhua2.setCheckRange("文化价值观");
		wenhua2.setTarget("");
		wenhua2.setType(2);
		wenhua2.setIsEdit(auth.getWenHuaEdit());
		wenhua2.setCheckWeight(new BigDecimal(0.15));
		return wenhua2;
	}

	public ResultDetailResp getWenHuaJiaZhiGuaResult1(BigDecimal sum) {
		ResultDetailResp tail1 = new ResultDetailResp();
		tail1.setKeyResult("文化价值观考核结果");
		tail1.setCheckWeight(new BigDecimal(0.3));
		tail1.setSuperScore("/");
		tail1.setAcquireScore(BigDecimalUtil.setScale(sum, 3));
		tail1.setScoreComment("/");
		tail1.setIsAdd(-1);
		return tail1;
	}




	public ResultDetailResp getWenHuaJiaZhiGuaResult2() {
		ResultDetailResp tail2 = new ResultDetailResp();
		tail2.setCheckRange("最终绩效考核评分");
		tail2.setAcquireScore(BigDecimal.ZERO);
		tail2.setScoreComment("/");
		tail2.setIsAdd(-1);
		return tail2;
	}

	public ResultDetailResp getLastResult(BigDecimal value) {
		ResultDetailResp tail3 = new ResultDetailResp();
		tail3.setCheckRange("最终绩效考核结果等级");
		tail3.setAcquireScore(BigDecimalUtil.setScale(value, 3));
		tail3.setScoreComment("/");
		tail3.setIsAdd(-1);
		return tail3;
	}



	public void insertWenHuaJiaZhiGua(String target, Long recordId, Long staffId,BigDecimal checkWeight) {
		ResultDetail wenhua1 = new ResultDetail();
		wenhua1.setTarget(target);
		wenhua1.setType(2);
		wenhua1.setCheckWeight(checkWeight);
		wenhua1.setStaffId(staffId);
		wenhua1.setRecordId(recordId);
		wenhua1.setKeyResult(Constant.WENHUAJIAZHIGUAN_TARGET);
		insertResultDetail(wenhua1);
	}

	@Override
	public String initRole(Long staffId,Long roleId){
		List<StaffRoleDto> staffRoles = new ArrayList<>();
		StaffRoleDto staffRole = new StaffRoleDto() ;
		staffRole.setStaffId(staffId);
		staffRole.setRoleId(roleId);
		staffRoles.add(staffRole);
		return JSON.toJSONString(staffRoles);
	}

    @Override
    public List<Step> getStepList(ResultRecord resultRecord) {
		Long staffId = resultRecord.getStaffId();
		int type = resultRecord.getType();
		List<Step> stepList = new ArrayList<>();
		StaffEntity mySelf = staffService.selectStaffById(staffId);
		List<FlowRecord> flowRecordList = flowRecordService.selectFlowRecordByResultRecordIdFlowId(resultRecord.getId());
		SimpleDateFormat myFmt2 = new SimpleDateFormat("MM-dd HH:mm");
		FlowRecord lastFlowRecord = null;
		if (CollectionUtils.isNotEmpty(flowRecordList)) {
			for (FlowRecord flowRecord : flowRecordList) {
				String name = flowRecord.getApprovalStaffName();
				String time = myFmt2.format(flowRecord.getGmtCreate());
				if (flowRecord.getStatus().equals(0)) {
					lastFlowRecord = flowRecord;
				}
				stepList.add(new Step(name, time, 1, ""));
			}
		}
		//approvalList = [ME,ONE_D,TWO_D,HR,BOSS]
		List<String> approvalList = new ArrayList<>();
		Map<String,String> roleNameMap = new HashMap<>();
		approvalList.add("ME");
		roleNameMap.put("ME",mySelf.getName());

		TwoTuple<Long, List<FlowDepartment>> flowInfo = resultRecordService.getFlowInfo(staffId, type);
		List<FlowDepartment> list = flowInfo.getSecond();

		List<FlowRelation> flowRelations = flowRelationService.selectFlowRelationAll();
		Map<String, FlowDepartment> staffEntityMap = list.stream().collect(Collectors.toMap(FlowDepartment::getDepartmentLevel, p -> p));

		Long flowId = flowInfo.getFirst();
		List<Flow> flows = flowService.selectByFlowId(flowId,0l);

		int flowIndex = lastFlowRecord != null ? lastFlowRecord.getFlowIndex() + 1 : 1;
		log.info("flowIndex = " + flowIndex);
		for (FlowRelation flowRelation : flowRelations) {
			FlowDepartment flowDepartment = staffEntityMap.get(flowRelation.getChild());
			if (flowDepartment != null || flowRelation.getCanReplace() == 0) {
				approvalList.add(flowRelation.getChild());
				String departmentLevel = flowRelation.getChild();
				if(flowDepartment != null ){
					StaffEntity flowStaff = staffService.selectStaffById(flowDepartment.getStaffId());
					roleNameMap.put(departmentLevel,flowStaff.getName());
				}else{
					Long roleId = flows.size() > flowIndex - 1 ? flows.get(flowIndex - 1).getRoleId() : null;
					List<StaffRoleDto> staffRoleDtos = new ArrayList<>();
					StaffEntity approvalStaff = resultRecordService.getApprovalStaff(resultRecord, departmentLevel, staffRoleDtos, roleId);
					roleNameMap.put(departmentLevel,approvalStaff.getName());
				}
			}
		}
		log.info("approvalList approval : " + Arrays.toString(approvalList.toArray()) + " roleNameMap : " + JSON.toJSONString(roleNameMap));
		for (int i = flowIndex; i < flowIndex + 10; i++) {
			int index = resultRecordService.getDepartmentLevelIndex(flows, i);
			if (index < 0 || index >= approvalList.size()) {
				break;
			}
			String departmentLevel = approvalList.get(index);
			stepList.add(new Step(roleNameMap.get(departmentLevel), "", 0, ""));
		}

		return stepList;
	}

	@Override
	public String getScoreLevel(double doubleValue) {
		if(doubleValue < 3.375){
			return "3.25";
		}else if(doubleValue < 3.5 ){
			return "3.5-";
		}else if (doubleValue < 3.583){
			return "3.5";
		}else if (doubleValue < 3.667){
			return "3.5+";
		}else if (doubleValue < 3.75){
			return "3.75-";
		}else if (doubleValue < 3.875){
			return "3.75";
		}else if (doubleValue < 4 ){
			return "3.75+";
		}else if (doubleValue == 4 ){
			return "4";
		}
		return "0";
	}

	@Override
	public List<ResultDetail> selectByRecordIdAndType(Long id, int type) {
		return resultDetailMapper.selectByRecordIdType(id,type);
	}

	@Override
	public Long insertResultDetails(List<ResultDetail> resultDetails){
		if(resultDetails.size() <= maxInsertSQL){
			return resultDetailMapper.insertResultDetails(resultDetails);
		}
		//下面防止sql语句过大
		Long count = Long.parseLong("0");
		int insert = 0;
		List<ResultDetail> resultDetails1 = new ArrayList<>();
		for (ResultDetail detail:resultDetails
		) {
			resultDetails1.add(detail);
			insert++;
			if(insert >= maxInsertSQL){
				count += resultDetailMapper.insertResultDetails(resultDetails1);
				resultDetails1.clear();
				insert = 0;
			}

		}
		if(resultDetails1.size() > 0){
			count += resultDetailMapper.insertResultDetails(resultDetails1);
		}
		return count;



	}

	@Override
	public List<ResultDetailDto> selectDtosByRecordId(Long id, Long modelId){
		return resultDetailMapper.selectDtosByRecordId(id, modelId);
	}

	@Override
	public int deleteResultDetailByRecordId(Long recordId){
		return resultDetailMapper.deleteResultDetailByRecordId(recordId);
	}

	@Override
	public ResultDetail selectNotNoticeResultDetailByBackId(Long backId){
		return resultDetailMapper.selectNotNoticeResultDetailByBackId(backId);
	}

	@Override
	public List<ResultDetail> selectNotNoticeResultDetailByRecordId(Long recordId){
		return resultDetailMapper.selectNotNoticeResultDetailByRecordId(recordId);
	}
}
