package com.seeyon.apps.src_ydctdatasync.quartz;

import cn.hutool.log.Log;
import com.seeyon.apps.common.config.ICstConfigApi;
import com.seeyon.apps.common.plugin.vo.ConfigVo;
import com.seeyon.apps.ext.quartz.AbstractQuartzTask;
import com.seeyon.apps.src_ydctdatasync.constants.YdzbdataSyncConstants;
import com.seeyon.apps.src_ydctdatasync.dao.FormExportUtil;
import com.seeyon.apps.src_ydctdatasync.dao.MyJdbcAgent;
import com.seeyon.apps.src_ydctdatasync.datamap.BzfAssetMode;
import com.seeyon.apps.src_ydctdatasync.datamap.ContractBillMode;
import com.seeyon.apps.src_ydctdatasync.datamap.ContractMode;
import com.seeyon.apps.src_ydctdatasync.datamap.GzcfAssetMode;
import com.seeyon.apps.src_ydctdatasync.datamap.GzfwAssetMode;
import com.seeyon.apps.src_ydctdatasync.datamap.GztdAssetMode;
import com.seeyon.apps.src_ydctdatasync.datamap.HydropowerRechargeDataMapMode;
import com.seeyon.apps.src_ydctdatasync.datamap.RefundDataMapMode;
import com.seeyon.apps.src_ydctdatasync.datasource.DataSource;
import com.seeyon.apps.src_ydctdatasync.utils.EnumMapUtils;
import com.seeyon.apps.src_ydctdatasync.utils.StatementQueryUtil;
import com.seeyon.apps.src_ydctdatasync.utils.TimeUtils;
import com.seeyon.cap4.form.api.FormApi4Cap4;
import com.seeyon.cap4.form.bean.FormBean;
import com.seeyon.cap4.form.bean.FormFieldBean;
import com.seeyon.cap4.form.bean.FormTableBean;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.organization.bo.V3xOrgDepartment;
import com.seeyon.ctp.organization.bo.V3xOrgMember;
import com.seeyon.ctp.organization.manager.OrgManager;
import com.seeyon.ctp.services.ServiceException;
import com.seeyon.ctp.util.JDBCAgent;
import com.seeyon.v3x.services.form.FormFactory;
import com.seeyon.v3x.services.form.bean.FormExport;
import org.springframework.beans.factory.DisposableBean;

import java.sql.Connection;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import static com.seeyon.apps.src_ydctdatasync.constants.YdzbdataSyncConstants.getPluginId;

public class YdzbDataSyncQuartz extends AbstractQuartzTask implements DisposableBean {

	private static Log log = Log.get(YdzbDataSyncQuartz.class);
	protected ICstConfigApi cstConfigApi = (ICstConfigApi) AppContext.getBean("cstConfigApi");
	private FormFactory formFactory;
	private DataSource ydzbThirdDataSource = (DataSource) AppContext.getBean("ydzbThirdDataSource");
	private DataSource myCusDataSource = new DataSource((javax.sql.DataSource)AppContext.getBean("dataSource"));
	private MyJdbcAgent agent = new MyJdbcAgent(myCusDataSource);
	private boolean prod;
	private FormApi4Cap4 formApi4Cap4 = null;
	public boolean isProd() {
		return prod;
	}

	public void setProd(boolean prod) {
		this.prod = prod;
	}
	public FormApi4Cap4 getFormApi4Cap4() {
		if (this.formApi4Cap4 == null) {
			this.formApi4Cap4 = (FormApi4Cap4)AppContext.getBean("formApi4Cap4");
		}

		return this.formApi4Cap4;
	}

	public FormFactory getFormFactory() {
		if (formFactory == null) {
			formFactory = (FormFactory) AppContext.getBean("formFactory");
		}
		return formFactory;
	}

	public void setFormFactory(FormFactory formFactory) {
		this.formFactory = formFactory;
	}

	@Override
	public String getName() {
		return "宜都城投资产数据同步任务";
	}

	@Override
	public String taskRun(String arg0) {
		if ("-1".equals(arg0)) {
			log.info("宜都城投资产数据同步任务不执行");
			return null;
		}
		log.info("宜都城投资产数据同步任务开始");
		long startTime = System.currentTimeMillis();
		try (Connection connection = ydzbThirdDataSource.getConnection()){
			CountDownLatch countDownLatch = new CountDownLatch(3);
			//线程1
			new Thread(()->{
                try {
                    processZcData(connection);
					countDownLatch.countDown();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                } catch (BusinessException e) {
                    throw new RuntimeException(e);
                } catch (ServiceException e) {
                    throw new RuntimeException(e);
                }finally {
					countDownLatch.countDown();
				}
            }).start();
			//线程2
			new Thread(()->{
				try {
					processContractData(connection);
				} catch (SQLException e) {
					throw new RuntimeException(e);
				} catch (BusinessException e) {
					throw new RuntimeException(e);
				} catch (ServiceException e) {
					throw new RuntimeException(e);
				}finally {
					countDownLatch.countDown();
				}
			}).start();
			DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			Date startDate = null;
			Date endDate = null;
			try {
				if (!"".equals(arg0) && arg0 != null) {
					String[] splits = arg0.split(",");
					for (int i = 0; i < splits.length; i++) {
						if(i == 0) {
							startDate = df.parse(splits[i]);
						}
						if(i == 1) {
							endDate = df.parse(splits[i]);
						}
					}
				}
			} catch (ParseException e) {
				log.error(e.getMessage(),e);
			}
			Date finalStartDate = startDate;
			Date finalEndDate = endDate;
			//线程3
			new Thread(()->{
                try {
                    processFeeData(connection, finalStartDate, finalEndDate);
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                } catch (BusinessException e) {
                    throw new RuntimeException(e);
                } catch (ServiceException e) {
                    throw new RuntimeException(e);
                }finally {
					countDownLatch.countDown();
				}
            }).start();
			countDownLatch.await();
			log.info("宜都城投资产数据同步任务结束,耗时:"+ (System.currentTimeMillis() - startTime)+ " ms");
		} catch (Exception e) {
			log.error("宜都城投资产数据同步任务执行失败");
			log.error(e.getMessage(),e);
		}
		return null;
	}

	//处理合同数据
	private void processContractData(Connection connection) throws SQLException, BusinessException, ServiceException {
		log.info("开始同步合同表数据");
		String countQuerySql = "SELECT count(*) FROM zb_contract;";
		String pageQuerySql = "SELECT * FROM zb_contract limit 100 OFFSET ?;";
		ContractMode contractMode = new ContractMode();
		contractMode.setAgent(agent);
		contractMode.setKsTableName(getBizConfigByKey(YdzbdataSyncConstants.ksTable));
		contractMode.setZcRootPcode(getBizConfigByKey(YdzbdataSyncConstants.zcRootEnumPCode));
		long count = StatementQueryUtil.queryCount(countQuerySql,connection, null);
		int totalPage = (int)Math.ceil((double)count / 100);
		for(int i = 0; i < totalPage;i++) {
			List<Map<String, Object>> contractDataList = StatementQueryUtil.queryList(pageQuerySql, connection, i*100);
			for (Map<String, Object> rowMap : contractDataList) {
				Map<String, Object> targetMap = new HashMap<>();
				contractMode.preProcess(rowMap);
				contractMode.transfer(targetMap,rowMap);
				Map<String,Object> subMap = (Map<String,Object>)targetMap.get("subTable");
				targetMap.remove("subTable");
				upsertData(getBizConfigByKey(YdzbdataSyncConstants.contractFormNo),
						convert2StringValue(targetMap),
						getBizConfigByKey(YdzbdataSyncConstants.contractTable),
						convert2StringValue(subMap),
						" WHERE field0003 = ?", (String) targetMap.get("合同编号"));
			}
		}
		log.info("合同表数据同步结束");
	}

	//处理费用数据
	private void processFeeData(Connection connection,Date startDate,Date endDate) throws SQLException, BusinessException, ServiceException {
		if(startDate == null) {
			startDate = TimeUtils.startOfYesterday();
		}else {
			startDate = TimeUtils.startOf(startDate);
		}
		if(endDate == null) {
			endDate = TimeUtils.startOf(new Date());
		}else {
			endDate = TimeUtils.startOf(endDate);
		}
		log.info("开始同步费用数据");
		processContractBillData(connection,startDate,endDate);
		processRefundData(connection,startDate,endDate);
		processHydpowerRechargeData(connection,startDate,endDate);
		log.info("费用数据同步结束");
	}

	//处理合同费用
	private void processContractBillData(Connection connection,Date startDate,Date endDate) throws SQLException, BusinessException, ServiceException {
		log.info("开始同步合同费用数据");
		String countQuerySql = "SELECT count(*) FROM zb_contract_bill where trade_reconciliation_time >= ? and trade_reconciliation_time <= ?;";
		String pageQuerySql = "SELECT * FROM zb_contract_bill where trade_reconciliation_time >= ? and trade_reconciliation_time <= ? limit 100 OFFSET ?;";
		ContractBillMode contractBillMode = new ContractBillMode();
		contractBillMode.setAgent(agent);
		contractBillMode.setZcRootPcode(getBizConfigByKey(YdzbdataSyncConstants.zcRootEnumPCode));
		long count = StatementQueryUtil.queryCount(countQuerySql,connection,startDate,endDate);
		int totalPage = (int)Math.ceil((double)count / 100);
		for(int i = 0; i < totalPage;i++) {
			List<Map<String, Object>> dataList = StatementQueryUtil.queryList(pageQuerySql, connection, startDate,endDate,i*100);
			for (Map<String, Object> rowMap : dataList) {
				Map<String, Object> targetMap = new HashMap<>();
				contractBillMode.preProcess(rowMap);
				contractBillMode.transfer(targetMap,rowMap);
				insertData(getBizConfigByKey(YdzbdataSyncConstants.feeFormNo),convert2StringValue(targetMap));
			}
		}
		log.info("合同费用数据同步完成");
	}

	private Map<String,String> convert2StringValue(Map<String,Object> oriMap) {
		Map<String,String> resMap = new HashMap<>();
		for (String key : oriMap.keySet()) {
			resMap.put(key,oriMap.get(key)+"");
		}
		return resMap;
	}

	//处理水电费
	private void processHydpowerRechargeData(Connection connection,Date startDate,Date endDate) throws SQLException, BusinessException, ServiceException {
		log.info("开始同步水电费数据");
		String countQuerySql = "SELECT count(*) FROM zb_hydropower_recharge where recharge_time >= ? and recharge_time <=?;";
		String pageQuerySql = "SELECT * FROM zb_hydropower_recharge where recharge_time >= ? and recharge_time <= ? limit 100 OFFSET ?;";
		HydropowerRechargeDataMapMode rechargeDataMapMode = new HydropowerRechargeDataMapMode();
		rechargeDataMapMode.setAgent(agent);
		rechargeDataMapMode.setZcRootPcode(getBizConfigByKey(YdzbdataSyncConstants.zcRootEnumPCode));
		long count = StatementQueryUtil.queryCount(countQuerySql,connection, startDate,endDate);
		int totalPage = (int)Math.ceil((double)count / 100);
		for(int i = 0; i < totalPage;i++) {
			List<Map<String, Object>> dataList = StatementQueryUtil.queryList(pageQuerySql, connection, startDate,endDate,i*100);
			for (Map<String, Object> rowMap : dataList) {
				Map<String, Object> targetMap = new HashMap<>();
				rechargeDataMapMode.preProcess(rowMap);
				rechargeDataMapMode.transfer(targetMap,rowMap);
				insertData(getBizConfigByKey(YdzbdataSyncConstants.feeFormNo),convert2StringValue(targetMap));
			}
		}
		log.info("水电费数据同步完成");
	}

	//处理退费
	private void processRefundData(Connection connection,Date startDate,Date endDate) throws SQLException, BusinessException, ServiceException {
		log.info("开始同步退费数据");
		String countQuerySql = "SELECT count(*) FROM zb_refund where create_time >= ? and create_time <= ?;";
		String pageQuerySql = "SELECT * FROM zb_refund where create_time >= ? and create_time <= ? limit 100 OFFSET ?;";
		RefundDataMapMode refundDataMapMode = new RefundDataMapMode();
		refundDataMapMode.setAgent(agent);
		refundDataMapMode.setZcRootPcode(getBizConfigByKey(YdzbdataSyncConstants.zcRootEnumPCode));
		long count = StatementQueryUtil.queryCount(countQuerySql,connection, startDate,endDate);
		int totalPage = (int)Math.ceil((double)count / 100);
		for(int i = 0; i < totalPage;i++) {
			List<Map<String, Object>> dataList = StatementQueryUtil.queryList(pageQuerySql,connection, startDate,endDate,i*100);
			for (Map<String, Object> rowMap : dataList) {
				Map<String, Object> targetMap = new HashMap<>();
				refundDataMapMode.preProcess(rowMap);
				refundDataMapMode.transfer(targetMap,rowMap);
				insertData(getBizConfigByKey(YdzbdataSyncConstants.feeFormNo),convert2StringValue(targetMap));
			}
		}
		log.info("退费数据同步结束");
	}

	//处理资产数据
	private void processZcData(Connection connection) throws SQLException, BusinessException, ServiceException {
		log.info("开始同步资产表数据");
		processBzfHouseData(connection);
		processGzcfData(connection);
		processGzfwData(connection);
		processGztdData(connection);
		log.info("资产表数据同步结束");
	}

	private void processGztdData(Connection connection) throws SQLException, BusinessException, ServiceException {
		log.info("开始同步国资土地数据");
		String countQuerySql = "SELECT count(*) FROM zb_gztd_house;";
		String pageQuerySql = "SELECT * FROM zb_gztd_house limit 100 OFFSET ?;";
		GztdAssetMode gztdAssetMode = new GztdAssetMode();
		gztdAssetMode.setAgent(agent);
		gztdAssetMode.setZcRootPcode(getBizConfigByKey(YdzbdataSyncConstants.zcRootEnumPCode));
		long count = StatementQueryUtil.queryCount(countQuerySql,connection, null);
		int totalPage = (int)Math.ceil((double)count / 100);
		for(int i = 0; i < totalPage;i++) {
			List<Map<String, Object>> dataList = StatementQueryUtil.queryList(pageQuerySql, connection, i*100);
			for (Map<String, Object> rowMap : dataList) {
				Map<String, Object> targetMap = new HashMap<>();
				gztdAssetMode.preProcess(rowMap);
				gztdAssetMode.transfer(targetMap,rowMap);
				upsertData(getBizConfigByKey(YdzbdataSyncConstants.zcFormNo),
							convert2StringValue(targetMap),
							getBizConfigByKey(YdzbdataSyncConstants.zcTable),
						" WHERE field0031 = ?",
						targetMap.get("资产编号") +"");
			}
		}
		log.info("国资土地数据同步完成");
	}

	private void processGzfwData(Connection connection) throws SQLException, BusinessException, ServiceException {
		log.info("开始同步国资房屋数据");
		String countQuerySql = "SELECT count(*) FROM zb_gzfw_house;";
		String pageQuerySql = "SELECT * FROM zb_gzfw_house limit 100 OFFSET ?;";
		GzfwAssetMode gzfwAssetMode = new GzfwAssetMode();
		gzfwAssetMode.setAgent(agent);
		gzfwAssetMode.setZcRootPcode(getBizConfigByKey(YdzbdataSyncConstants.zcRootEnumPCode));
		long count = StatementQueryUtil.queryCount(countQuerySql,connection, null);
		int totalPage = (int)Math.ceil((double)count / 100);
		for(int i = 0; i < totalPage;i++) {
			List<Map<String, Object>> dataList = StatementQueryUtil.queryList(pageQuerySql, connection, i*100);
			for (Map<String, Object> rowMap : dataList) {
				Map<String, Object> targetMap = new HashMap<>();
				gzfwAssetMode.preProcess(rowMap);
				gzfwAssetMode.transfer(targetMap,rowMap);
				upsertData(getBizConfigByKey(YdzbdataSyncConstants.zcFormNo),
						convert2StringValue(targetMap),
						getBizConfigByKey(YdzbdataSyncConstants.zcTable),
						" WHERE field0031 = ?",
						targetMap.get("资产编号") + "");
			}
		}
		log.info("国资房屋数据同步结束");
	}

	private void processGzcfData(Connection connection) throws SQLException, BusinessException, ServiceException {
		log.info("开始同步国资厂房数据");
		String countQuerySql = "SELECT count(*) FROM zb_gzcf_house;";
		String pageQuerySql = "SELECT * FROM zb_gzcf_house limit 100 OFFSET ?;";
		GzcfAssetMode gzcfAssetMode = new GzcfAssetMode();
		gzcfAssetMode.setAgent(agent);
		gzcfAssetMode.setZcRootPcode(getBizConfigByKey(YdzbdataSyncConstants.zcRootEnumPCode));
		long count = StatementQueryUtil.queryCount(countQuerySql,connection, null);
		int totalPage = (int)Math.ceil((double)count / 100);
		for(int i = 0; i < totalPage;i++) {
			List<Map<String, Object>> dataList = StatementQueryUtil.queryList(pageQuerySql, connection, i*100);
			for (Map<String, Object> rowMap : dataList) {
				Map<String, Object> targetMap = new HashMap<>();
				gzcfAssetMode.preProcess(rowMap);
				gzcfAssetMode.transfer(targetMap,rowMap);
				upsertData(getBizConfigByKey(YdzbdataSyncConstants.zcFormNo),
						convert2StringValue(targetMap),
						getBizConfigByKey(YdzbdataSyncConstants.zcTable),
						" WHERE field0031 = ?",
						targetMap.get("资产编号") + "");
			}
		}
		log.info("国资厂房数据同步完成");
	}

	private String getCreatorDept(String loginName) {
		OrgManager orgManager = (OrgManager) AppContext.getBean("orgManager");
		try {
			V3xOrgMember member = orgManager.getMemberByLoginName(loginName);
			Long departmentId = member.getOrgDepartmentId();
			V3xOrgDepartment department = orgManager.getDepartmentById(departmentId);
			return department == null ? "" : department.getName();
		} catch (BusinessException e) {
			return null;
		}
	}

	private void handleParentXzData(Connection connection) throws ServiceException, SQLException {
		log.info("开始同步父级小区数据");
		String queryXq = "select zh.village_name,zh.land_nature,zh.property_mortgage from zb_bzf_house zh where land_nature is not null and property_mortgage is not null group By zh.village_name,zh.land_nature,zh.property_mortgage;";

		String rootCode = getBizConfigByKey(YdzbdataSyncConstants.zcRootEnumPCode);
		String xqzcpLevelValue = EnumMapUtils.getEnumItemValue(rootCode, agent, "资产等级", "父级");
		String zcTypeFwValue = EnumMapUtils.getEnumItemValue(rootCode, agent, "资产分类（资产系统）", "房屋");
		String zcTypeLevel2 = EnumMapUtils.getEnumItemValue(rootCode, agent, "资产分类（资产系统）", "保障性住房");
		String xqzcBlock = EnumMapUtils.getEnumItemValue(rootCode, agent, "资产分类（资产系统）", "03不动产");
		String xqzcStatus = EnumMapUtils.getEnumItemValue(rootCode, agent, "资产状态", "待出租");
		String xqzcFeature = EnumMapUtils.getEnumItemValue(rootCode, agent, "资产性质", "非流动资产");
		String xqzz = EnumMapUtils.getEnumItemValue(rootCode, agent, "房屋用途", "住宅");
		String xqrental_type = EnumMapUtils.getEnumItemValue(rootCode, agent, "租售类型", "只租不售");
		String xqhs = EnumMapUtils.getEnumItemValue(rootCode, agent, "房屋体系", "保租房");
		List<Map<String, Object>> resList = StatementQueryUtil.queryList(queryXq,connection,null);
		if (resList != null && resList.size() > 0) {
			for (Map<String, Object> mapT : resList) {
				List<String> params = new ArrayList<>();
				String villageQuerySql = "SELECT 1 FROM " + getBizConfigByKey(YdzbdataSyncConstants.zcTable) + " WHERE field0027 = ? and field0023 = ? and field0037 =?;";
				params.add(xqzcpLevelValue);
				params.add(zcTypeFwValue);
				params.add(mapT.get("village_name") + "");
				List<Map<String, Object>> list = (List<Map<String, Object>>) agent.execute(villageQuerySql, params);
				DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				if (list == null || list.isEmpty()) {
					//保障性住房小区的资产信息若不存在，则插入
					Map<String, String> villageInsertInfo = new HashMap<>();
					villageInsertInfo.put("建档部门", getCreatorDept(getBizConfigByKey(YdzbdataSyncConstants.loginName)));//建档部门
					villageInsertInfo.put("建档人员", "系统管理员");//建档人员
					villageInsertInfo.put("建档日期", df.format(new Date()));//建档日期
					villageInsertInfo.put("资产板块", xqzcBlock);//资产板块
					villageInsertInfo.put("建档单位", "住保置业");//建档单位
					villageInsertInfo.put("资产层级", xqzcpLevelValue);//资产层级
					villageInsertInfo.put("数据来源", "住保资产系统(自定义)");//数据来源
					villageInsertInfo.put("资产名称", mapT.get("village_name") + "");//资产名称
					villageInsertInfo.put("资产状态", xqzcStatus);//资产状态
					villageInsertInfo.put("资产性质", xqzcFeature);//资产性质
					villageInsertInfo.put("资产类型", zcTypeFwValue);//资产类型
					villageInsertInfo.put("资产二级类型", zcTypeLevel2);//资产二级类型
					villageInsertInfo.put("资产种类", "保障性住房");//资产种类
					villageInsertInfo.put("所属小区", mapT.get("village_name") + "");//小区
					villageInsertInfo.put("用途", xqzz);//用途
					villageInsertInfo.put("租售类型", xqrental_type);//租售类型
					villageInsertInfo.put("房屋体系", xqhs);//房屋体系
					villageInsertInfo.put("土地性质", EnumMapUtils.getEnumItemValue(rootCode, agent, "土地资产", mapT.get("land_nature") + ""));//土地性质
					villageInsertInfo.put("是否产权抵押", EnumMapUtils.getEnumItemValue(rootCode, agent, "是否产权抵押", mapT.get("property_mortgage") + "")); //是否产权抵押
					FormExport formExport = new FormExport();
					formExport.setValues(FormExportUtil.setFormValue(villageInsertInfo));
					getFormFactory().importBusinessFormData(getBizConfigByKey(YdzbdataSyncConstants.loginName), getBizConfigByKey(YdzbdataSyncConstants.zcFormNo), formExport, new String[]{});
				}
			}
		}

	}

	private void processBzfHouseData(Connection connection) throws SQLException, BusinessException, ServiceException {
		log.info("开始同步保障房数据");
		handleParentXzData(connection);
		String countQuerySql = "SELECT count(*) FROM zb_bzf_house;";
		String pageQuerySql = "SELECT * FROM zb_bzf_house limit 100 OFFSET ?;";
		BzfAssetMode bzfAssetMode = new BzfAssetMode();
		bzfAssetMode.setAgent(agent);
		bzfAssetMode.setFormNo(getBizConfigByKey(YdzbdataSyncConstants.zcFormNo));
		bzfAssetMode.setZcRootPcode(getBizConfigByKey(YdzbdataSyncConstants.zcRootEnumPCode));
		long count = StatementQueryUtil.queryCount(countQuerySql,connection, null);
		int totalPage = (int)Math.ceil((double)count / 100);
		for(int i = 0; i < totalPage;i++) {
			List<Map<String, Object>> dataList = StatementQueryUtil.queryList(pageQuerySql, connection, i*100);
			for (Map<String, Object> rowMap : dataList) {
				Map<String, Object> targetMap = new HashMap<>();
				Map<String,Object> temp = new HashMap<>();
				temp.putAll(rowMap);
				temp.put("loginName",getBizConfigByKey(YdzbdataSyncConstants.loginName));
				temp.put("zcTable",getBizConfigByKey(YdzbdataSyncConstants.zcTable));
				bzfAssetMode.preProcess(temp);
				bzfAssetMode.transfer(targetMap,temp);
				upsertData(getBizConfigByKey(YdzbdataSyncConstants.zcFormNo),
						convert2StringValue(targetMap),
						getBizConfigByKey(YdzbdataSyncConstants.zcTable),
						" WHERE field0031 = ?",
						targetMap.get("资产编号") + "");
			}
		}
		log.info("保障房数据同步结束");
	}

	private void upsertData(String formNo,Map<String, String> targetMap,String table,String whereSql,String param) throws BusinessException, SQLException, ServiceException {
		//不存在则插入，存在则更新
		List<String> params = new ArrayList<>();
		params.add(param);
		String querySql = "SELECT * FROM " + table + " "+ whereSql +";";
		Map<String,Object> existData = null;
		List<Map<String, Object>> resList = (List<Map<String, Object>>) agent.execute(querySql, params);
		existData = resList == null || resList.size() == 0 ? null : resList.get(0);
		if (existData != null && existData.size() > 0) {
			FormBean cap4FormBean = this.getFormApi4Cap4().getFormByFormCode(formNo);
			Map<String, Object> temp = new HashMap<>();
			for (FormTableBean tableBean : cap4FormBean.getTableList()) {
				if (tableBean.getDbTableName().contains("formmain")) {
					for (String key : targetMap.keySet()) {
						FormFieldBean fieldBean = tableBean.getFieldMap4Display().get(key);
						temp.put(fieldBean.getColumnName(), targetMap.get(key));
					}
				}
			}
			for (String key : temp.keySet()) {
				existData.put(key, temp.get(key) + "");
			}
			Map<String, Object> updateSqlMap = generateUpdateSql(existData, table, " WHERE ID = ?", param);
			agent.execute((String) updateSqlMap.get("sql"), (List) updateSqlMap.get("params"));
		} else {
			FormExport formExport = new FormExport();
			formExport.setValues(FormExportUtil.setFormValue(targetMap));
			getFormFactory().importBusinessFormData(getBizConfigByKey(YdzbdataSyncConstants.loginName), formNo, formExport, new String[]{});
		}

	}

	private void insertData(String formNo,Map<String, String> targetMap) throws BusinessException, SQLException, ServiceException {
		FormExport formExport = new FormExport();
		formExport.setValues(FormExportUtil.setFormValue(targetMap));
		getFormFactory().importBusinessFormData(getBizConfigByKey(YdzbdataSyncConstants.loginName), formNo,formExport, new String[] {});
	}

	private void upsertData(String formNo,Map<String, String> targetMap,String table,Map<String, String> subTableMap,String whereSql,String param) throws BusinessException, SQLException, ServiceException {
		//不存在则插入，存在则更新
		List<String> params = new ArrayList<>();
		params.add(param);
		String querySql = "SELECT * FROM " + table +" " + whereSql +";";
		Map<String,Object> existData = null;
		List<Map<String, Object>> resList = (List<Map<String, Object>>) agent.execute(querySql, params);
		existData = resList == null || resList.size() == 0 ? null : resList.get(0);
		if (existData != null && existData.size() > 0) {
			FormBean cap4FormBean = this.getFormApi4Cap4().getFormByFormCode(formNo);
			Map<String, Object> temp = new HashMap<>();
			for (FormTableBean tableBean : cap4FormBean.getTableList()) {
				if (tableBean.getDbTableName().contains("formmain")) {
					for (String key : targetMap.keySet()) {
						FormFieldBean fieldBean = tableBean.getFieldMap4Display().get(key);
						temp.put(fieldBean.getColumnName(), targetMap.get(key));
					}
				}
			}
			for (String key : temp.keySet()) {
				existData.put(key, temp.get(key) + "");
			}
			Map<String, Object> updateSqlMap = generateUpdateSql(existData, table, " WHERE ID = ?", param);
			agent.execute((String) updateSqlMap.get("sql"), (List) updateSqlMap.get("params"));
		} else {
			FormExport formExport = new FormExport();
			formExport.setValues(FormExportUtil.setFormValue(targetMap));
			formExport.setSubordinateForms(FormExportUtil.setSubordinateFormValue(subTableMap));
			getFormFactory().importBusinessFormData(getBizConfigByKey(YdzbdataSyncConstants.loginName), formNo, formExport, new String[]{});
		}

	}

	private Map<String, Object> generateUpdateSql(Map<String, Object> fieldValues, String tableName, String whereClause,Object clauseValue) {
		if (fieldValues == null || fieldValues.isEmpty()) {
			throw new IllegalArgumentException("Field values cannot be null or empty");
		}
		if (tableName == null || tableName.trim().isEmpty()) {
			throw new IllegalArgumentException("Table name cannot be null or empty");
		}
		if (whereClause == null || whereClause.trim().isEmpty()) {
			throw new IllegalArgumentException("Where clause cannot be null or empty");
		}
		StringBuilder sqlBuilder = new StringBuilder("UPDATE ").append(tableName).append(" SET ");
		List<Object> params = new ArrayList<>();
		// Build the SET clause
		int fieldCount = 0;
		for (Map.Entry<String, Object> entry : fieldValues.entrySet()) {
			if(entry.getValue() == null || "".equals(entry.getValue()) || "null".equals(entry.getValue())) {
				continue;
			}
			if(entry.getKey().equals("ID")) {
				if(whereClause.contains("ID")) {
					clauseValue = entry.getValue();
				}
				continue;
			}
			if (fieldCount > 0) {
				sqlBuilder.append(", ");
			}
			sqlBuilder.append(entry.getKey()).append(" = ?");
			params.add(entry.getValue());
			fieldCount++;
		}
		params.add(clauseValue);
		// Append the WHERE clause
		sqlBuilder.append(whereClause);
		// Create result map
		sqlBuilder.append(";");
		Map<String, Object> result = new HashMap<>();
		result.put("sql", sqlBuilder.toString());
		result.put("params", params);
		return result;
	}

	@Override
	public void destroy() throws Exception {
		ydzbThirdDataSource.close();
		myCusDataSource.close();
	}

	private String getBizConfigByKey(YdzbdataSyncConstants key) {
		ConfigVo config = cstConfigApi.getConfig(getPluginId());
		if(prod) {
			return config.getParamVal(key.name());
		}else {
			return key.getDefaultValue();
		}
	}
}
