package com.uas.platform.b2b.mobile.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.ui.ModelMap;

import com.uas.platform.b2b.dao.UserBaseInfoDao;
import com.uas.platform.b2b.mobile.dao.AppFlowOperationDao;
import com.uas.platform.b2b.mobile.dao.ApprovalLogDao;
import com.uas.platform.b2b.mobile.dao.VacationDao;
import com.uas.platform.b2b.mobile.enumeration.MobileStatus;
import com.uas.platform.b2b.mobile.model.AppFlowOperation;
import com.uas.platform.b2b.mobile.model.AppLog;
import com.uas.platform.b2b.mobile.model.ApprovalLog;
import com.uas.platform.b2b.mobile.model.Vacation;
import com.uas.platform.b2b.mobile.service.VacationService;
import com.uas.platform.b2b.model.FlowNode;
import com.uas.platform.b2b.service.ApprovalFlowService;
import com.uas.platform.core.model.PageInfo;
import com.uas.platform.core.model.PageParams;

@Service
public class VacationServiceImpl implements VacationService {

	@Autowired
	private VacationDao vacationDao;

	@Autowired
	private ApprovalFlowService approvalFlowService;

	@Autowired
	private ApprovalLogDao approvalLogDao;

	@Autowired
	private AppFlowOperationDao appFlowOperationDao;

	@Autowired
	private UserBaseInfoDao userBaseInfoDao;

	@Override
	public ModelMap getAllVacation(Long emcode, Integer pageNumber, Integer pageSize, Long enuu) {
		ModelMap map = new ModelMap();
		PageParams params = new PageParams();
		params.setCount(pageSize);
		params.setPage(pageNumber);
		String sorting = "{\"orderdate\":\"desc\"}";
		params.setSorting(sorting);
		final PageInfo pageInfo = new PageInfo(params);
		pageInfo.filter("emcode", emcode);
		pageInfo.filter("enuu", enuu);
		Page<Vacation> vacations = vacationDao.findAll(new Specification<Vacation>() {
			@Override
            public Predicate toPredicate(Root<Vacation> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				return query.where(pageInfo.getPredicates(root, query, builder)).getRestriction();
			}
		}, pageInfo);
		map.put("listdata", vacations.getContent());
		return map;
	}

	@Override
	public ModelMap saveVacation(Vacation vacation) {
		ModelMap map = new ModelMap();
		Vacation va = new Vacation();
		Long id = 0L;
		if (vacation.getVa_id() == null) {// 新增单据
			vacation.setVa_statuscode(MobileStatus.ENTERING.name());
			vacation.setVa_status(MobileStatus.ENTERING.getPhrase());
			SimpleDateFormat sdf = new SimpleDateFormat("yyMMmmSS");
			vacation.setVa_code("AL" + sdf.format(new Date()));
			vacation.setVa_date(new Date());
			vacation.setOrderdate(new Date());
			vacation.setVa_emname(userBaseInfoDao.findByUserUU(vacation.getEmcode()).getUserName());
			vacation.setVa_recorder(userBaseInfoDao.findByUserUU(vacation.getEmcode()).getUserName());
			va = vacationDao.save(vacation);
			id = va.getVa_id();
			if (id != null) {
				map.put("success", true);
				map.put("va_id", id);
			} else {
				map.put("success", false);
			}
		} else { // 更新单据
			va = vacationDao.findOne(vacation.getVa_id());
			va.setVa_statuscode(MobileStatus.ENTERING.name());
			va.setVa_status(MobileStatus.ENTERING.getPhrase());
			va.setVa_vacationtype(vacation.getVa_vacationtype());
			va.setVa_date(new Date());
			va.setOrderdate(new Date());
			va.setVa_startime(vacation.getVa_startime());
			va.setVa_endtime(vacation.getVa_endtime());
			va.setVa_remark(vacation.getVa_remark());
			va.setVa_emname(userBaseInfoDao.findByUserUU(vacation.getEmcode()).getUserName());
			va.setVa_recorder(userBaseInfoDao.findByUserUU(vacation.getEmcode()).getUserName());
			va = vacationDao.save(va);
			id = va.getVa_id();
			map.put("success", true);
			map.put("va_id", id);
		}

		// 审批流
		// TODO 暂时这里先只做人员的线路
		String appName = MobileStatus.VACATION.getPhrase();
		FlowNode node = approvalFlowService.getNodeInfoByEnuuAndEmcodeAndAppName(vacation.getEnuu(),
				vacation.getEmcode(), appName);
		Integer nodelevel = -1;
		if (node != null) {
			nodelevel = node.getNodelev();
		}
		Integer maxNode = approvalFlowService.getMaxNodeByEnuuAndAppName(vacation.getEnuu(), appName);
		if (maxNode != null) {// 审批流存在才创建审批流任务
			if (nodelevel < maxNode) {
				AppLog log = new AppLog();
				log.setStatus(MobileStatus.ENTERING.getPhrase());
				log.setStatusCode(MobileStatus.ENTERING.name());
				log.setSourceid(id);
				log.setSourcedate(new Date());
				log.setKeyvalue(id);
				log.setCaller(appName);
				log.setEmcode(vacation.getEmcode());
				log.setEnuu(vacation.getEnuu());
				for (int i = nodelevel + 1; i <= maxNode; i++) {
					ApprovalLog applog = new ApprovalLog(log);
					applog.setNodedealman(approvalFlowService
							.getNodeInfoByEnuuAndAppNameAndNodelev(vacation.getEnuu(), appName, i).getEmcode());
					applog.setNodename(approvalFlowService
							.getNodeInfoByEnuuAndAppNameAndNodelev(vacation.getEnuu(), appName, i).getNodename());
					applog.setProcessid(approvalFlowService
							.getNodeInfoByEnuuAndAppNameAndNodelev(vacation.getEnuu(), appName, i).getId());
					applog = approvalLogDao.save(applog);
					node = approvalFlowService.getNodeInfoByEnuuAndAppNameAndNodelev(vacation.getEnuu(), appName,
							nodelevel + 1);
					if (applog.getId() != null && applog.getNodedealman()
							.equals(approvalFlowService
									.getNodeInfoByEnuuAndAppNameAndNodelev(vacation.getEnuu(), appName, nodelevel + 1)
									.getEmcode())) {
						// 新增待审批
						AppFlowOperation operation = new AppFlowOperation();
						operation.setCaller(appName);
						operation.setDealname(vacation.getVa_recorder());
						operation.setDealuu(vacation.getEmcode());
						operation.setKeyvalue(applog.getId());
						operation.setNodedealname(node.getEmname());
						operation.setRecorddate(new Date());
						operation.setStatus(MobileStatus.UNAUDIT.getPhrase());
						operation.setStatuscode(MobileStatus.UNAUDIT.name());
						operation.setEnuu(vacation.getEnuu());
						operation.setNodedealuu(node.getEmcode());
						operation.setNodelevel(node.getNodelev());
						operation.setSourceid(vacation.getVa_id());
						operation = appFlowOperationDao.save(operation);
						if (operation.getId() != null) {
							if (id != null) {// 更新单据状态
								vacation = vacationDao.findOne(id);
								vacation.setVa_status(MobileStatus.COMMITED.getPhrase());
								vacation.setVa_statuscode(MobileStatus.COMMITED.name());
								vacationDao.save(vacation);
							}
							map.put("success", true);
						} else {
							map.put("success", false);
						}
					}
				}
			}
			if (Objects.equals(nodelevel, maxNode)) {
				if (id != null) {// 更新单据状态
					vacation = vacationDao.findOne(id);
					vacation.setVa_status(MobileStatus.AUDITED.getPhrase());
					vacation.setVa_statuscode(MobileStatus.AUDITED.name());
					vacationDao.save(vacation);
				}
			}
		}
		return map;
	}

}
