package com.jpsoft.shinestar.modules.workflow.service.impl;

import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;

import cn.hutool.core.util.StrUtil;
import com.jpsoft.shinestar.config.WxConfig;
import com.jpsoft.shinestar.modules.base.entity.*;
import com.jpsoft.shinestar.modules.base.service.*;
import com.jpsoft.shinestar.modules.business.dto.ExaminePersonDTO;
import com.jpsoft.shinestar.modules.business.entity.*;
import com.jpsoft.shinestar.modules.business.service.*;
import com.jpsoft.shinestar.modules.common.utils.JwtUtil2;
import com.jpsoft.shinestar.modules.common.utils.TypeNameUtil;
import com.jpsoft.shinestar.modules.common.utils.WechatMessageUtil;
import com.jpsoft.shinestar.modules.workflow.entity.*;
import com.jpsoft.shinestar.modules.workflow.service.*;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.jpsoft.shinestar.modules.workflow.dao.ProcinstDAO;
import com.github.pagehelper.Page;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.github.pagehelper.PageHelper;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

@Transactional(rollbackFor = Exception.class)
@Component(value="procinstService")
public class ProcinstServiceImpl implements ProcinstService {
	@Resource(name="procinstDAO")
	private ProcinstDAO procinstDAO;

	@Value("${jwt.secret}")
	private String jwtSecret;

	@Autowired
	private WxConfig wxConfig;

	@Autowired
	private TemplateDepartmentService templateDepartmentService;

	@Autowired
	private ProcessActivityService processActivityService;

	@Autowired
	private PersonInfoService personInfoService;

	@Autowired
	private AdjustShiftService adjustShiftService;

	@Autowired
	private RequestForLeaveInfoService requestForLeaveInfoService;

	@Autowired
	private BusinessOutService businessOutService;

	@Autowired
	private WorkOverPersonService workOverPersonService;

	@Autowired
	private CustomerDiningRecordService customerDiningRecordService;

	@Autowired
	private WorkOverService workOverService;

	@Autowired
	private CarryThingsOutFactoryService carryThingsOutFactoryService;

	@Autowired
	private SupplementWorkService supplementWorkService;

	@Autowired
	private ProcessSetService processSetService;

	@Autowired
	private ProcinstActivityService procinstActivityService;

	@Autowired
	private ProcinstActUserService procinstActUserService;

	@Autowired
	private ProcinstService procinstService;

	@Autowired
	private ProcessTemplateService processTemplateService;

	@Autowired
	private YearRequestForLeaveInfoService yearRequestForLeaveInfoService;

	@Override
	public Procinst get(String id) {
		// TODO Auto-generated method stub
		return procinstDAO.get(id);
	}

	@Override
	public int insert(Procinst model) {
		// TODO Auto-generated method stub
		//model.set${PkFieldName}(UUID.randomUUID().toString());

		return procinstDAO.insert(model);
	}

	@Override
	public int update(Procinst model) {
		// TODO Auto-generated method stub
		return procinstDAO.update(model);
	}

	@Override
	public int delete(String id) {
		// TODO Auto-generated method stub
		return procinstDAO.delete(id);
	}

	@Override
	public boolean exist(String id) {
		// TODO Auto-generated method stub
		int count = procinstDAO.exist(id);

		return count > 0 ? true : false;
	}

	@Override
	public List<Procinst> list() {
		// TODO Auto-generated method stub
		return procinstDAO.list();
	}

	@Override
	public Page<Procinst> pageSearch(Map<String, Object> searchParams, int pageNumber, int pageSize,boolean count,List<Sort> sortList) {
        Page<Procinst> page = PageHelper.startPage(pageNumber,pageSize,count).doSelectPage(()->{
            procinstDAO.search(searchParams,sortList);
        });

        return page;
	}

	@Override
	public Procinst findByBusinessKey(String businessKey) {
		return procinstDAO.findByBusinessKey(businessKey);
	}

	@Override
	public String addProcInst(String businessKey, String businessName, String formId, PersonPopedom personPopedom,
							  String activityId, String processTemplateId, Map<String,Object> conditions) throws Exception{
		if (StrUtil.isBlank(processTemplateId)){
			List<TemplateDepartment> templateDepartments = templateDepartmentService.findByFormIdDepartmentId(formId, personPopedom.getCompanyId(),personPopedom.getPersonRoleId());
			if (templateDepartments.size() == 0) {
				throw new Exception("您的部门没有相应流程模板");
			}
			TemplateDepartment templateDepartment = templateDepartments.get(0);
			processTemplateId = templateDepartment.getProcessTemplateId();
		}


		ProcessTemplate processTemplate = processTemplateService.get(processTemplateId);

		/*if (processTemplate.getOrderNum() == 0) {
			throw new Exception("模板步骤数目错误");
		}*/

		Procinst procinst = new Procinst();
		procinst.setId(UUID.randomUUID().toString());
		procinst.setProcessTemplateId(processTemplate.getId());
		procinst.setBusinessKey(businessKey);
		procinst.setPersonId(personPopedom.getPersonId());
		procinst.setType(TypeNameUtil.getOperationName(formId));
		procinst.setCreateTime(new Date());
		procinstService.insert(procinst);



	//	List<ProcessActivity> processActivityList = processActivityService.findByTemplateIdAndRoleId(processTemplate.getId(),personPopedom.getPersonRoleId());

		List<ProcessActivity> processActivityList = null;
		if (StringUtils.isNotBlank(activityId)){
			ProcessActivity processActivity = processActivityService.get(activityId);
			processActivityList = processActivityService.findByTemplateIdAndRoleIdAndCondition(processTemplate.getId(),personPopedom.getPersonRoleId(),processActivity.getCondition());
		}else {
			processActivityList = processActivityService.findByTemplateIdAndRoleId(processTemplate.getId(),personPopedom.getPersonRoleId());
		}

		for (int n = 1; n <= processActivityList.size(); n++) {
			ExaminePersonDTO examinePersonDTO = processSetService.getExaminePerson(procinst.getId(), processTemplate.getId(), personPopedom, n,conditions);

			//创建流程主表
			/*adjustShift.setProcinstId(procinst.getId());
			update(adjustShift);*/

			//创建流程二级表
			ProcinstActivity procinstActivity = new ProcinstActivity();
			procinstActivity.setId(UUID.randomUUID().toString());
			procinstActivity.setProcinstId(procinst.getId());
			procinstActivity.setActivityIndex(n);
			procinstActivity.setActivityId(examinePersonDTO.getActivityId());
			if (n == 1) {
				procinstActivity.setStatus("1");
			} else {
				procinstActivity.setStatus("0");
			}

			procinstActivity.setAction("0");
			procinstActivity.setRemark("待审核");
			procinstActivity.setCreateTime(new Date());
			procinstActivityService.insert(procinstActivity);

			//创建流程三级表,写入审核人
			List<String> personIdList = Arrays.asList(examinePersonDTO.getPersonIds().split(","));
			if (personIdList.size() > 0) {
				for (String personId : personIdList) {
					ProcinstActUser procinstActUser = new ProcinstActUser();
					procinstActUser.setId(UUID.randomUUID().toString());
					procinstActUser.setProcinstActivityId(procinstActivity.getId());
					procinstActUser.setUserId(personId);
					procinstActUser.setType("1");
					procinstActUser.setAction("0");
					procinstActUser.setRemark("待审核");
					procinstActUser.setCreateTime(new Date());
					procinstActUserService.insert(procinstActUser);
				}
			}

			//写入抄送人
			String ccPersonIds = examinePersonDTO.getCcPersonIds();
			if (StringUtils.isNotBlank(ccPersonIds)) {
				List<String> ccPersonIdList = Arrays.asList(ccPersonIds.split(","));
				for (String ccPersonId : ccPersonIdList) {
					ProcinstActUser procinstActUser = new ProcinstActUser();
					procinstActUser.setId(UUID.randomUUID().toString());
					procinstActUser.setProcinstActivityId(procinstActivity.getId());
					procinstActUser.setUserId(ccPersonId);
					procinstActUser.setType("2");
					procinstActUser.setAction("0");
					procinstActUser.setRemark("待抄送");
					procinstActUser.setCreateTime(new Date());
					procinstActUserService.insert(procinstActUser);
				}
			}


		}

		return procinst.getId();

	}

	@Override
	public void revoke(PersonPopedom personPopedom, String id) throws Exception {


		Procinst procinst = findByBusinessKey(id);

		if (procinst == null){
			throw new Exception("参数错误");
		}

		List<ProcinstActivity> list = procinstActivityService.findByProcinstId(procinst.getId());

		//过滤出已处理的记录
		List<ProcinstActivity> temp = list.stream().filter(p -> !"0".equals(p.getAction())).collect(Collectors.toList());

		if (temp.size()>0){
			throw new Exception("已存在处理过的记录，不可撤销");
		}


		ProcinstActivity procinstActivity = procinstActivityService.findProcinstIdAndStatus(procinst.getId(),"1");
		if (procinstActivity != null){
			procinstActivity.setStatus("0");
			procinstActivityService.update(procinstActivity);
		}



		//调班
		if ("1".equals(procinst.getType())) {
			AdjustShift adjustShift = adjustShiftService.get(procinst.getBusinessKey());
			adjustShift.setStatus("6");
			adjustShift.setUpdateTime(new Date());
			adjustShiftService.update(adjustShift);
		}
		//请假
		if ("2".equals(procinst.getType())) {
			RequestForLeaveInfo requestForLeaveInfo = requestForLeaveInfoService.get(procinst.getBusinessKey());
			requestForLeaveInfo.setStatus(6);
			requestForLeaveInfo.setUpdateTime(new Date());
			requestForLeaveInfoService.update(requestForLeaveInfo);

		}
		//出差
		if ("3".equals(procinst.getType())) {
			BusinessOut businessOut = businessOutService.get(procinst.getBusinessKey());
			businessOut.setStatus("6");
			businessOut.setUpdateTime(new Date());
			businessOutService.update(businessOut);

		}
		//补卡，批量补卡
		if ("4".equals(procinst.getType()) || "5".equals(procinst.getType())) {
			SupplementWork supplementWork = supplementWorkService.get(procinst.getBusinessKey());
			supplementWork.setStatus("6");
			supplementWork.setUpdateTime(new Date());
			supplementWorkService.update(supplementWork);
		}
		//加班，批量加班
		if ("6".equals(procinst.getType()) || "7".equals(procinst.getType())) {
			WorkOver workOver = workOverService.get(procinst.getBusinessKey());
			workOver.setStatus("6");
			workOver.setUpdateTime(new Date());
			workOverService.update(workOver);
		}
		//携物出厂
		if ("8".equals(procinst.getType())) {
			CarryThingsOutFactory carryThingsOutFactory = carryThingsOutFactoryService.get(procinst.getBusinessKey());
			carryThingsOutFactory.setAuditStatus("6");
			carryThingsOutFactory.setUpdateTime(new Date());
			carryThingsOutFactoryService.update(carryThingsOutFactory);
		}
		//接待就餐
		if ("9".equals(procinst.getType())){
			CustomerDiningRecord customerDiningRecord = customerDiningRecordService.get(procinst.getBusinessKey());
			customerDiningRecord.setStatus("6");
			customerDiningRecord.setUpdateTime(new Date());
			customerDiningRecordService.update(customerDiningRecord);
		}

		//年假
		if ("11".equals(procinst.getType())) {
			YearRequestForLeaveInfo yearRequestForLeaveInfo = yearRequestForLeaveInfoService.get(procinst.getBusinessKey());
			yearRequestForLeaveInfo.setStatus(6);
			yearRequestForLeaveInfo.setUpdateTime(new Date());
			yearRequestForLeaveInfoService.update(yearRequestForLeaveInfo);
		}
	}
}