package com.artfess.bpm.persistence.manager.impl;

import com.artfess.base.exception.BaseException;
import com.artfess.base.feign.SystemConfigFeignService;
import com.artfess.base.feign.UCFeignService;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.query.QueryFilter;
import com.artfess.base.query.QueryOP;
import com.artfess.base.util.BeanUtils;
import com.artfess.base.util.FileUtil;
import com.artfess.base.util.JAXBUtil;
import com.artfess.base.util.JsonUtil;
import com.artfess.base.util.StringUtil;
import com.artfess.base.util.ThreadMsgUtil;
import com.artfess.base.util.UniqueIdUtil;
import com.artfess.base.util.ZipUtil;
import com.artfess.bpm.persistence.dao.BpmReportActDao;
import com.artfess.bpm.persistence.dao.BpmReportListDao;
import com.artfess.bpm.persistence.manager.BpmReportActManager;
import com.artfess.bpm.persistence.manager.BpmReportListManager;
import com.artfess.bpm.persistence.model.BpmReportAct;
import com.artfess.bpm.persistence.model.BpmReportList;
import com.artfess.bpm.persistence.model.BpmReportXml;
import com.artfess.bpm.persistence.model.BpmReportXmlList;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author tangxin
 *
 */
@Service("bpmReportListManager")
public class BpmReportListManagerImpl extends BaseManagerImpl<BpmReportListDao, BpmReportList> implements BpmReportListManager {


	@Resource
	BpmReportActManager bpmReportActManager;
	@Resource
	BpmReportActDao bpmReportActDao;
	@Resource
	SystemConfigFeignService systemConfigFeignService;
	@Resource
	UCFeignService ucFeignService;


	@Override
    @Transactional
	public void removeByIds(String... ids){
		for (String id : ids) {
			this.remove(id);
		}
	}

    @Transactional
	public void remove(String id){
		BpmReportList reportList =  super.get(id);
		if(BeanUtils.isNotEmpty(reportList)){
			bpmReportActManager.removeByReportId(id);
		}
		super.remove(id);
	}

	@Override
	public Map<String, String> exportData(List<String> ids) throws Exception {
		Map<String, String> map = new HashMap<>();
		BpmReportXmlList bpmReportXmlList = new BpmReportXmlList();
		for (String id : ids) {
			QueryWrapper wrapper = new QueryWrapper();
			wrapper.eq("report_id_", id);
			List<BpmReportAct> bpmReportActList = bpmReportActDao.selectList(wrapper);
			for (BpmReportAct bpmReportAct: bpmReportActList) {
				ObjectNode prop =  (ObjectNode) JsonUtil.toJsonNode(bpmReportAct.getPorp());
				//流程范围类型：“1”流程；“2”流程分类
				String flowType = JsonUtil.getString(prop,"flowType","1");
				List<String> flowTypeKeys = new ArrayList<>();
				if ("2".equals(flowType)){
					//流程分类ID
					String flowTypeIds = JsonUtil.getString(prop, "id");
					if (StringUtil.isNotEmpty(flowTypeIds)){
						QueryFilter queryFilter = QueryFilter.build();
						queryFilter.addFilter("id_", flowTypeIds, QueryOP.IN);
						ObjectNode sysTypeObjNode = systemConfigFeignService.getAllSysType(queryFilter);
						if (BeanUtils.isNotEmpty(sysTypeObjNode) && BeanUtils.isNotEmpty(sysTypeObjNode.get("rows"))) {
							for (JsonNode sysTypeNode : sysTypeObjNode.get("rows")) {
								String flowTypeKey = JsonUtil.getString(sysTypeNode,"typeKey");
								if (StringUtil.isNotEmpty(flowTypeKey)){
									flowTypeKeys.add(flowTypeKey);
								}
							}
							if (!flowTypeKeys.isEmpty()){
								bpmReportAct.setFlowTypeKeys(flowTypeKeys);
							}
						}
					}
				}
				String orgIds = JsonUtil.getString(prop, "orgIds");
				if (StringUtil.isNotEmpty(orgIds)){
					ArrayNode orgArrayNode = ucFeignService.getOrgsByIds(orgIds);
					if (BeanUtils.isNotEmpty(orgArrayNode)){
						List<String> orgCodes = new ArrayList<>();
						for(JsonNode orgNode:orgArrayNode) {
							String code = JsonUtil.getString(orgNode,"code");
							if (StringUtil.isNotEmpty(code)){
								orgCodes.add(code);
							}
						}
						if (!orgCodes.isEmpty()){
							bpmReportAct.setOrgCodes(orgCodes);
						}
					}
				}
				String userIds = JsonUtil.getString(prop, "userIds");
				if (StringUtil.isNotEmpty(userIds)){
					ArrayNode userArrayNode = ucFeignService.getUserByIds(userIds);
					if (BeanUtils.isNotEmpty(userArrayNode)){
						List<String> userAccounts = new ArrayList<>();
						for(JsonNode userNode:userArrayNode) {
							String userAccount = JsonUtil.getString(userNode,"account");
							if (StringUtil.isNotEmpty(userAccount)){
								userAccounts.add(userAccount);
							}
						}
						if (!userAccounts.isEmpty()){
							bpmReportAct.setUserAccounts(userAccounts);
						}
					}
				}
			}
			BpmReportXml bpmReportXml = new BpmReportXml();
			BpmReportList bpmReport = this.get(id);
			bpmReportXml.setBpmReport(bpmReport);
			bpmReportXml.setBpmReportActList(bpmReportActList);
			bpmReportXmlList.addBpmReportXml(bpmReportXml);
		}
		try {
			String xml = JAXBUtil.marshall(bpmReportXmlList, BpmReportXmlList.class);
			map.put("bpmReports.bpm.xml", xml);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("导出失败！" + e.getMessage(), e);
		}
		return map;
	}

	@Override
	@Transactional
	public void importData(MultipartFile file) {
		String unZipFilePath = null;
		try {
			String rootRealPath = Paths.get(FileUtil.getIoTmpdir(), "attachFiles/unZip").toString();
			FileUtil.createFolder(rootRealPath, true);
			ZipUtil.unZipFile(file, rootRealPath);
			String name = file.getOriginalFilename();
			String fileDir = StringUtil.substringBeforeLast(name, ".");
			unZipFilePath = Paths.get(rootRealPath, fileDir).toString();
			String xml = FileUtil.readFile(Paths.get(unZipFilePath, "bpmReports.bpm.xml").toString());
			if (StringUtil.isEmpty(xml)) {
				throw new BaseException("导入的xml文件没有内容！");
			}
			BpmReportXmlList list = (BpmReportXmlList) JAXBUtil.unmarshall(xml, BpmReportXmlList.class);
			List<BpmReportXml> bpmReportXmlList = list.getBpmReportXmlList();
			for (BpmReportXml bpmReportxml : bpmReportXmlList) {
				importData(bpmReportxml);
			}
		} catch (Exception e) {
			throw new BaseException(e.getMessage(), e);
		} finally {
			if (StringUtil.isNotEmpty(unZipFilePath)) {
				File formDir = new File(unZipFilePath);
				if (formDir.exists()) {
					FileUtil.deleteDir(formDir);
				}
			}
		}
	}

	private void importData(BpmReportXml bpmReportxml) throws Exception {
		BpmReportList bpmReport = bpmReportxml.getBpmReport();
		QueryWrapper wrapper = new QueryWrapper();
		wrapper.eq("name_", bpmReport.getName());
		List<BpmReportList> bpmReportList = baseMapper.selectList(wrapper);
		if (bpmReportList != null && !bpmReportList.isEmpty()) {
			ThreadMsgUtil.addMapMsg2("bpmReportsSkipped", String.format("<div style='margin-left:12px; margin-top:6px;'>%s</div>",bpmReport.getName() + ""));
			return;
		}
		String reportId = UniqueIdUtil.getSuid();
		bpmReport.setId(reportId);
		this.create(bpmReport);
		wrapper = new QueryWrapper();
		wrapper.eq("report_id_", reportId);
		List<BpmReportAct> bpmReportActList = bpmReportxml.getBpmReportActList();
		for (BpmReportAct bpmReportAct : bpmReportActList){
			ObjectNode prop = (ObjectNode)JsonUtil.toJsonNode(bpmReportAct.getPorp());
			String flowType = JsonUtil.getString(prop,"flowType","1");
			if ("2".equals(flowType)){
				List<String> flowTypeKeys = bpmReportAct.getFlowTypeKeys();
				if (flowTypeKeys != null && !flowTypeKeys.isEmpty()){
					String flowTypeKeysStr = String.join(",", flowTypeKeys);
					QueryFilter queryFilter = QueryFilter.build();
					queryFilter.addFilter("typeGroupKey", "FLOW_TYPE", QueryOP.EQUAL);
					queryFilter.addFilter("typeKey", flowTypeKeysStr, QueryOP.IN);
					ObjectNode sysTypeObjNode = systemConfigFeignService.getAllSysType(queryFilter);
					if (BeanUtils.isNotEmpty(sysTypeObjNode) && BeanUtils.isNotEmpty(sysTypeObjNode.get("rows"))) {
						List<String> flowTypeIds = new ArrayList<>();
						for (JsonNode sysTypeNode : sysTypeObjNode.get("rows")) {
							String flowTypeId = JsonUtil.getString(sysTypeNode,"id");
							if (StringUtil.isNotEmpty(flowTypeId)){
								flowTypeIds.add(flowTypeId);
							}
						}
						if (!flowTypeIds.isEmpty()){
							String flowTypeIdsStr = String.join(",", flowTypeIds);
							prop.put("id", flowTypeIdsStr);
						}
					}
				}
			}
			List<String> orgCodes = bpmReportAct.getOrgCodes();
			if (orgCodes != null && !orgCodes.isEmpty()){
				String orgCodesStr = String.join(",", orgCodes);
				ArrayNode orgArrayNode = ucFeignService.getOrgsByCodes(orgCodesStr);
				if (BeanUtils.isNotEmpty(orgArrayNode)){
					List<String> orgIds = new ArrayList<>();
					List<String> orgNames = new ArrayList<>();
					for (JsonNode orgNode: orgArrayNode){
						String orgId = JsonUtil.getString(orgNode, "id");
						if (StringUtil.isNotEmpty(orgId)){
							orgIds.add(orgId);
						}
						String orgName = JsonUtil.getString(orgNode, "name");
						if (StringUtil.isNotEmpty(orgName)){
							orgNames.add(orgName);
						}
					}
					if (!orgIds.isEmpty()){
						String orgIdsStr = String.join(",", orgIds);
						prop.put("orgIds", orgIdsStr);
					}
					if (!orgNames.isEmpty()){
						String orgNamesStr = String.join(",", orgNames);
						prop.put("orgNames", orgNamesStr);
					}
				}
			}
			List<String> userAccounts = bpmReportAct.getUserAccounts();
			if (userAccounts != null && !userAccounts.isEmpty()){
				String userAccountsStr = String.join(",", userAccounts);
				ArrayNode userArrayNode = ucFeignService.getUserByAccounts(userAccountsStr);
				if (BeanUtils.isNotEmpty(userArrayNode)){
					List<String> userIds = new ArrayList<>();
					List<String> userNames = new ArrayList<>();
					for (JsonNode userNode: userArrayNode){
						String userId = JsonUtil.getString(userNode, "id");
						if (StringUtil.isNotEmpty(userId)){
							userIds.add(userId);
						}
						String userName = JsonUtil.getString(userNode, "fullname");
						if (StringUtil.isNotEmpty(userName)){
							userNames.add(userName);
						}
					}
					//"部门id"和"用户id"都保存到orgIds
					if (!userIds.isEmpty()){
						String userIdsStr = String.join(",", userIds);
						prop.put("orgIds", userIdsStr);
					}
					if (!userNames.isEmpty()){
						String userNamesStr = String.join(",", userNames);
						prop.put("orgNames", userNamesStr);
					}
				}
			}
			bpmReportAct.setPorp(JsonUtil.toJsonString(prop));
			String actId = UniqueIdUtil.getSuid();
			bpmReportAct.setId(actId);
			bpmReportAct.setReportId(reportId);
			bpmReportActDao.insert(bpmReportAct);
		}
		ThreadMsgUtil.addMapMsg2("bpmReportsSaved", String.format("<div style='margin-left:12px; margin-top:6px;'>%s</div>",bpmReport.getName() + ""));
	}
}
