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

import java.math.BigDecimal;
import java.util.*;
import javax.annotation.Resource;

import com.jpsoft.shinestar.modules.base.entity.*;
import com.jpsoft.shinestar.modules.base.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.jpsoft.shinestar.modules.base.entity.PersonInfo;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import com.jpsoft.shinestar.modules.base.dao.PersonPopedomDAO;
import com.github.pagehelper.Page;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.github.pagehelper.PageHelper;

@Transactional
@Component(value="personPopedomService")
public class PersonPopedomServiceImpl implements PersonPopedomService {
	@Resource(name="personPopedomDAO")
	private PersonPopedomDAO personPopedomDAO;

	@Autowired
	private CompanyInfoService companyInfoService;

	@Autowired
	private PersonInfoService personInfoService;

	@Autowired
	private ApplicationExamineService applicationExamineService;

	@Autowired
	private PersonRoleInfoService personRoleInfoService;

	@Autowired
	private PersonRoleIconService personRoleIconService;

	@Autowired
	private CompanyStructureInfoService companyStructureInfoService;

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

	@Override
	public int insert(PersonPopedom model) {
		// TODO Auto-generated method stub
		//model.setId(UUID.randomUUID().toString());

		return personPopedomDAO.insert(model);
	}

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

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

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

		return count > 0 ? true : false;
	}

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

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

        return page;
	}

	@Override
	public Page<PersonPopedom> pageSearch2(Map<String, Object> searchParams, int pageNumber, int pageSize,boolean count,List<Sort> sortList) {
		Page<PersonPopedom> page = PageHelper.startPage(pageNumber,pageSize,count).doSelectPage(()->{
			personPopedomDAO.search2(searchParams,sortList);
		});

		return page;
	}

	@Override
	public int countByPerson(Long personId){
		return personPopedomDAO.countByPerson(personId);
	}

	@Override
	public PersonPopedom findOneByPersonId(Long personId){
		return personPopedomDAO.findOneByPersonId(personId);
	}

	@Override
	public List<PersonPopedom> findByPersonId(Long id) {
		return personPopedomDAO.findByPersonId(id);
	}

	@Override
	public  List<PersonPopedom> findByCompanyIdAndRoleIds(String companyId,String personRoleId){
		return personPopedomDAO.findByCompanyIdAndRoleIds(companyId,personRoleId);
	}

	@Override
	public PersonPopedom findByVerify(PersonPopedom personPopedom){
		return personPopedomDAO.findByVerify(personPopedom);
	}

	@Override
	public PersonPopedom autoInsert(PersonInfo personInfo) throws Exception{
		List<PersonPopedom> personPopedomList = findByPersonId(personInfo.getId());
		if (personPopedomList.size()>0){
			return personPopedomList.get(0);
		}

		CompanyInfo companyInfo = companyInfoService.get(personInfo.getCompanyId());
		PersonRoleInfo personRoleInfo = personRoleInfoService.findByRoleNameAndSceneId("员工",companyInfo.getSceneId());
		if (personRoleInfo == null){
			throw new Exception("所属公司无对应员工角色");
		}
		List<CompanyStructureInfo> companyStructureInfoList = companyStructureInfoService.findByCompanyId(companyInfo.getId());
		PersonPopedom personPopedom = new PersonPopedom();
		personPopedom.setId(UUID.randomUUID().toString());
		personPopedom.setPersonId(personInfo.getId());
		if (companyStructureInfoList.size()>0){
			personPopedom.setCompanyStructureId(companyStructureInfoList.get(0).getId());
		}
		personPopedom.setShowIconId(personRoleIconService.getDefaultIcon(personRoleInfo.getId()));
		personPopedom.setCompanyId(personInfo.getCompanyId());
		personPopedom.setPersonRoleId(personRoleInfo.getId());
		personPopedom.setDelFlag(false);
		personPopedom.setCreateTime(new Date());
		insert(personPopedom);

		return personPopedom;

	}

	@Override
	public List<PersonPopedom> findByCompanyIdAndRoleIdList(String serviceCompanyId, List<String> personRoloIds) {
		return personPopedomDAO.findByCompanyIdAndRoleIdList(serviceCompanyId,personRoloIds);
	}

	@Override
	public List<PersonPopedom> findByRelationPopedomId(String relationPopedomId){
		return personPopedomDAO.findByRelationPopedomId(relationPopedomId);
	}

	@Override
	public List<PersonPopedom> findByCompanyId(String companyId) {
		return personPopedomDAO.findByCompanyId(companyId);
	}

	@Override
	public List<PersonPopedom> findByCompanyList(List<CompanyInfo> companyInfoList) {
		return personPopedomDAO.findByCompanyList(companyInfoList);
	}

	@Override
	public Integer findNumByCompanyId(String companyId) {
		return personPopedomDAO.findNumByCompanyId(companyId);
	}

	@Override
	public Integer findNumByCompanyList(List<CompanyInfo> companyInfoList) {
		return personPopedomDAO.findNumByCompanyList(companyInfoList);
	}

	@Override
	public List<PersonPopedom> findByCompanyListAndName(List<CompanyInfo> companyInfoList, String name) {
		return personPopedomDAO.findByCompanyListAndName(companyInfoList,name);
	}

	@Override
	public List<PersonPopedom> findByPersonIdAndCompanyCode(Long personId, String companyCode) {
		return personPopedomDAO.findByPersonIdAndCompanyCode(personId, companyCode);
	}

	@Override
	public PersonPopedom hasEnableAttendance(Long personId,String companyCode) {
		PersonPopedom personPopedom = personPopedomDAO.hasEnableAttendance(personId, companyCode);

		return personPopedom;
	}

	@Override
	public List<PersonPopedom> findByCompanyIdAndEnableAttendance(List<CompanyInfo> companyInfoList, boolean enableAttendance) {
		return personPopedomDAO.findByCompanyIdAndEnableAttendance(companyInfoList,enableAttendance);
	}

	@Override
	public List<PersonPopedom> findByPersonIdAndRoleIdList(Long personId, List<PersonRoleIcon> personRoleIconList) {
		return personPopedomDAO.findByPersonIdAndRoleIdList(personId,personRoleIconList);
	}

	@Override
	public List<PersonPopedom> findApprovalList(PersonInfo personInfo, String type, Integer level, BigDecimal days) throws Exception {
		PersonPopedom personPopedom = get(personInfo.getPopedom());

		if (personPopedom == null) {
			throw new Exception("您的身份有误");
		}

		CompanyInfo companyInfo = companyInfoService.get(personPopedom.getCompanyId());

		List<PersonInfo> personInfoList = new ArrayList<>();
		List<PersonPopedom> dataList = new ArrayList<>();

		//查询用户的审核人
		List<PersonPopedom> personPopedomList = new ArrayList<>();

		ApplicationExamine applicationExamine = null;

		List<ApplicationExamine> applicationExamineList = applicationExamineService.findByApplicationCompanyAndRoleAndTypeAndDays(personPopedom.getCompanyId(), personPopedom.getPersonRoleId(), type, level, days);

		if (applicationExamineList.size() > 0) {
			applicationExamine = applicationExamineList.get(0);
		} else {
			//查询上级单位（设置了包括下级单位）有没有设置相同角色的设置
			CompanyInfo parent = null;
			int loopNum = 10;
			int zIndex = 0;

			if (StringUtils.isNotEmpty(companyInfo.getParentId())) {
				parent = companyInfoService.get(companyInfo.getParentId());
			}

			while (parent != null && zIndex < loopNum) {
				applicationExamineList = applicationExamineService.findByApplicationCompanyAndRoleAndTypeAndDays(parent.getId(), personPopedom.getPersonRoleId(), type, level, days);

				if (applicationExamineList.size() > 0 && applicationExamineList.get(0).getIncludeSubordinate()) {
					applicationExamine = applicationExamineList.get(0);
					break;
				}

				if ("1".equals(parent.getUnitType()) || StringUtils.isEmpty(companyInfo.getParentId())) {
					//如果是单位类型是公司或没有上级单位，则不再往上级查找
					break;
				} else {
					parent = companyInfoService.get(parent.getParentId());
					zIndex++;
				}
			}
		}

		if (applicationExamine != null) {
			List<PersonPopedom> personPopedoms = findByCompanyIdAndRoleIds(applicationExamine.getExamineCompanyId(), applicationExamine.getExamineRoleId());
			personPopedomList.addAll(personPopedoms);
		} else {
			//如果没有，则按照采用默认规则：本部门上级领导审批，部门没有上级领导则到上级部门找领导。
			PersonRoleInfo personRoleInfo = personRoleInfoService.get(personPopedom.getPersonRoleId());

			String parentRoleId = personRoleInfo.getParentId();

			String companyId = companyInfo.getId();

			//最多向上级单位查询10次
			int loopNum = 10;
			int zIndex = 0;

			while (personPopedomList.size() == 0 && zIndex < loopNum) {
				//当前单位中有没有拥有上级身份的人
				List<PersonPopedom> personPopedoms = new ArrayList<>();

				if (StringUtils.isNotEmpty(parentRoleId)) {
					personPopedoms = findByCompanyIdAndRoleIds(companyId, parentRoleId);
				}

				if (personPopedoms.size() > 0) {
					personPopedomList.addAll(personPopedoms);
				} else {
					PersonRoleInfo parentRole = null;

					if (StringUtils.isNotEmpty(parentRoleId)) {
						parentRole = personRoleInfoService.get(parentRoleId);
					}

					if (parentRole == null) {
						//当前单位没有上级身份，则单位向上查询
						CompanyInfo current = companyInfoService.get(companyId);

						if ("1".equals(current.getUnitType())) {
							//当前单位是公司，则不再往上级查找
							break;
						}

						//切换到上级单位继续查询
						companyId = current.getParentId();

						/**
						 切换为上级单位时，此时没有修改当前身份，比如在下级单位查询时，
						 身份最后会切换为高层，在上级单位中就只需要查询高层即可
						 **/
						if (StringUtils.isNotEmpty(personRoleInfo.getParentId())) {
							parentRoleId = personRoleInfo.getParentId();
						}
						else{
							parentRoleId = personRoleInfo.getId();
						}

						zIndex++;
					} else {
						//切换到上级身份
						parentRoleId = parentRole.getParentId();
						zIndex++;
					}

					if (StringUtils.isEmpty(companyId)) {
						//没有上级单位
						break;
					}
				}
			}
		}

		if (personPopedomList.size() > 0) {
			for (PersonPopedom personPopedom1 : personPopedomList) {

				if (!dataList.contains(personPopedom1)) {
					PersonInfo personInfo1 = personInfoService.get(personPopedom1.getPersonId());
					if (personInfo1 != null && !personInfoList.contains(personInfo1)) {
						personPopedom1.setPersonName(personInfo1.getName());
						personPopedom1.setFaceImageUrl(personInfo1.getFaceImageUrl());
						dataList.add(personPopedom1);
					}

				}

                    /*PersonInfo personInfo1 = personInfoService.get(personPopedom1.getPersonId());
                    if (personInfo1 != null && !personInfoList.contains(personInfo1)) {
                        personInfoList.add(personInfo1);
                    }*/
			}
		}
		return dataList;
	}

	@Override
	public PersonPopedom hasEnableAttendanceByCompanyId(Long personId, String companyId) {
		PersonPopedom personPopedom = personPopedomDAO.hasEnableAttendanceByCompanyId(personId, companyId);

		return personPopedom;
	}

	@Override
	public List<PersonPopedom> findByPersonIdCompanyId(Long personId, String companyId) {
		return personPopedomDAO.findByPersonIdCompanyId(personId,companyId);
	}

	@Override
	public List<PersonPopedom> findByPersonIdAndRoleId(Long personId, String personRoleId) {
		return personPopedomDAO.findByPersonIdAndRoleId(personId,personRoleId);
	}

	@Override
	public List<PersonPopedom> findByCompanyIdAndEnableRegisterExamine(String companyId, boolean enableRegisterExamine) {
		return personPopedomDAO.findByCompanyIdAndEnableRegisterExamine(companyId,enableRegisterExamine);
	}

	@Override
	public PersonPopedom findByIdIgnoreDel(String personPopedomId) {
		return personPopedomDAO.findByIdIgnoreDel(personPopedomId);
	}
}