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

import java.text.SimpleDateFormat;
import java.util.*;

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 org.springframework.util.CollectionUtils;

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.FeePleaseDao;
import com.uas.platform.b2b.mobile.dao.FeePleaseDetailDao;
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.FeePlease;
import com.uas.platform.b2b.mobile.model.FeePleaseDetail;
import com.uas.platform.b2b.mobile.service.FeePleaseService;
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 FeePleaseServiceImpl implements FeePleaseService {

	@Autowired
	private FeePleaseDetailDao feePleaseDetailDao;

	@Autowired
	private FeePleaseDao feePleaseDao;

	@Autowired
	private ApprovalFlowService approvalFlowService;

	@Autowired
	private ApprovalLogDao approvalLogDao;

	@Autowired
	private AppFlowOperationDao appFlowOperationDao;

	@Autowired
	private UserBaseInfoDao userBaseInfoDao;

	@Override
	public ModelMap saveFeePlease(FeePlease feePlease, List<FeePleaseDetail> feePleaseDetails) {
		ModelMap map = new ModelMap();
		Long id = 0L;
		if (feePlease.getFp_id() == null) {// 新增单据
			SimpleDateFormat sdf = new SimpleDateFormat("yyMMmmSS");
			feePlease.setFp_code("FP" + sdf.format(new Date()));
			feePlease.setFp_status(MobileStatus.ENTERING.getPhrase());
			feePlease.setFp_statuscode(MobileStatus.ENTERING.name());
			feePlease.setFp_recorddate(new Date());
			feePlease.setOrderdate(new Date());
			feePlease.setFp_people2(userBaseInfoDao.findByUserUU(feePlease.getEmcode()).getUserName());
			Set<FeePleaseDetail> feeDetails = new HashSet<FeePleaseDetail>();
			if (!CollectionUtils.isEmpty(feePleaseDetails)) {
				for (FeePleaseDetail feePleaseDetail : feePleaseDetails) {
					feePleaseDetail.setFeePlease(feePlease);
					feeDetails.add(feePleaseDetail);
				}
			}
			feePleaseDetails = feePleaseDetailDao.save(feeDetails);
			if (!CollectionUtils.isEmpty(feePleaseDetails)) {
				map.put("success", true);
				id = feePleaseDetails.get(0).getFeePlease().getFp_id();
				map.put("fp_id", id);
			} else {
				map.put("success", false);
			}
		} else { // 更新单据操作
			FeePlease fee = feePleaseDao.findOne(feePlease.getFp_id());
			id = feePlease.getFp_id();
			if (fee != null) {
				fee.setFp_status(MobileStatus.ENTERING.getPhrase());
				fee.setFp_statuscode(MobileStatus.ENTERING.name());
				fee.setFp_recorddate(new Date());
				fee.setOrderdate(new Date());
				fee.setFp_v3(feePlease.getFp_v3());
				fee.setFp_prestartdate(feePlease.getFp_prestartdate());
				fee.setFp_preenddate(feePlease.getFp_preenddate());
				fee.setEmcode(feePlease.getEmcode());
				fee.setFp_people2(userBaseInfoDao.findByUserUU(feePlease.getEmcode()).getUserName());
				feePleaseDao.save(fee);
				if (!CollectionUtils.isEmpty(feePleaseDetails)) {
					for (FeePleaseDetail feedetail : feePleaseDetails) {
						if (feedetail.getFpd_id() != null) {
							FeePleaseDetail detail = feePleaseDetailDao.findOne(feedetail.getFpd_id());
							detail.setFpd_address(feedetail.getFpd_address());
							detail.setFpd_detno(feedetail.getFpd_detno());
							detail.setFpd_location(feedetail.getFpd_location());
							feePleaseDetailDao.save(detail);
						}
					}
				}
			}
			map.put("fp_id", id);
			map.put("success", false);
		}
		String appName = MobileStatus.FEEPLEASE.getPhrase();
		FlowNode node = approvalFlowService.getNodeInfoByEnuuAndEmcodeAndAppName(feePlease.getEnuu(),
				feePlease.getEmcode(), appName);
		Integer nodelevel = -1;
		if (node != null) {
			nodelevel = node.getNodelev();
		}
		Integer maxNode = approvalFlowService.getMaxNodeByEnuuAndAppName(feePlease.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(feePlease.getEmcode());
				log.setEnuu(feePlease.getEnuu());
				for (int i = nodelevel + 1; i <= maxNode; i++) {
					ApprovalLog applog = new ApprovalLog(log);
					applog.setNodedealman(approvalFlowService
							.getNodeInfoByEnuuAndAppNameAndNodelev(feePlease.getEnuu(), appName, i).getEmcode());
					applog.setNodename(approvalFlowService
							.getNodeInfoByEnuuAndAppNameAndNodelev(feePlease.getEnuu(), appName, i).getNodename());
					applog.setProcessid(approvalFlowService
							.getNodeInfoByEnuuAndAppNameAndNodelev(feePlease.getEnuu(), appName, i).getId());
					applog = approvalLogDao.save(applog);
					node = approvalFlowService.getNodeInfoByEnuuAndAppNameAndNodelev(feePlease.getEnuu(), appName,
							nodelevel + 1);
					if (applog.getId() != null && applog.getNodedealman().equals(approvalFlowService
									.getNodeInfoByEnuuAndAppNameAndNodelev(feePlease.getEnuu(), appName, nodelevel + 1)
									.getEmcode())) {
						// 新增待审批
						AppFlowOperation operation = new AppFlowOperation();
						operation.setCaller(appName);
						operation.setDealname(feePlease.getFp_people2());
						operation.setDealuu(feePlease.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(feePlease.getEnuu());
						operation.setNodedealuu(node.getEmcode());
						operation.setNodelevel(node.getNodelev());
						operation.setSourceid(id);
						operation = appFlowOperationDao.save(operation);
						if (operation.getId() != null) {
							if (id != null) {
								feePlease = feePleaseDao.findOne(id);
								feePlease.setFp_status(MobileStatus.COMMITED.getPhrase());
								feePlease.setFp_statuscode(MobileStatus.COMMITED.name());
								feePleaseDao.save(feePlease);
							}
							map.put("success", true);
						} else {
							map.put("success", false);
						}
					}
				}
			}
			if (Objects.equals(nodelevel, maxNode)) {
				if (id != null) {
					feePlease = feePleaseDao.findOne(id);
					feePlease.setFp_status(MobileStatus.AUDITED.getPhrase());
					feePlease.setFp_statuscode(MobileStatus.AUDITED.name());
					feePleaseDao.save(feePlease);
				}
			}
		}
		return map;
	}

	@Override
	public ModelMap getFeePlease(Long enuu, Long emcode, Integer pageNumber, Integer pageSize) {
		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<FeePlease> feePleases = feePleaseDao.findAll(new Specification<FeePlease>() {
			@Override
			public Predicate toPredicate(Root<FeePlease> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				return query.where(pageInfo.getPredicates(root, query, builder)).getRestriction();
			}
		}, pageInfo);
		map.put("data", feePleases.getContent());
		return map;
	}
}
