package com.zfire.jiasm.syncdata.service.impl;

import com.zfire.jiasm.syncdata.service.PrepareService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.CallableStatementCreator;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class PrepareServiceImpl implements PrepareService {

	@Autowired
	private JdbcTemplate jdbcTemplate;

	public List<Map<String, Object>> getTaskData() {
		List<Map<String, Object>> result = jdbcTemplate
				.queryForList("SELECT * FROM itf_fa_to_gree_prepare_rule order by id ");
		return result;
	}

	@Override
	public List<Map<String, Object>> getSourceData(String srcTabName, Date updateTime) {
		List<Map<String, Object>> result = jdbcTemplate.queryForList(
				"SELECT * FROM " + srcTabName + " where upload_notify_flag=1 order by updatetime,id ", new Object[] {});
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void prepareData(String synProcName, int taskId, Date updateTime, String workerOrderNo, int orderId,
			String remoteId, boolean isNeedGenRemoteId) throws Exception {

		Map<String, Object> result = jdbcTemplate.execute(new CallableStatementCreator() {

			public CallableStatement createCallableStatement(Connection con) throws SQLException {


				// 过程名，源表中的ID，源表中的数据最后修改时间，源表中的工单号，源表中的id,空值，false

				CallableStatement cs = null;
				if (workerOrderNo == null) {

					cs = con.prepareCall("{call " + synProcName + "(?,?,?,?,?)}");
					cs.setInt(1, orderId);
					cs.registerOutParameter(2, Types.BOOLEAN);
					cs.registerOutParameter(3, Types.VARCHAR);

				} else {

					if (isNeedGenRemoteId) {
						cs = con.prepareCall("{call " + synProcName + "(?,?,?,?,?)}");
						cs.setString(1, workerOrderNo);
						cs.setInt(2, orderId);
						cs.setString(3, remoteId);
						cs.registerOutParameter(4, Types.BOOLEAN);
						cs.registerOutParameter(5, Types.VARCHAR);
					} else {
						cs = con.prepareCall("{call " + synProcName + "(?,?,?,?)}");
						cs.setString(1, workerOrderNo);
						cs.setInt(2, orderId);
						cs.registerOutParameter(3, Types.BOOLEAN);
						cs.registerOutParameter(4, Types.VARCHAR);
					}

				}

				return cs;
			}
		}, new CallableStatementCallback<Map<String, Object>>() {

			public Map<String, Object> doInCallableStatement(CallableStatement cs)
					throws SQLException, DataAccessException {

				cs.execute();

				int startIndex;
				if (workerOrderNo == null) {
					startIndex = 2;
				} else {
					if (isNeedGenRemoteId) {
						startIndex = 4;
					} else {
						startIndex = 3;
					}
				}

				boolean status = cs.getBoolean(startIndex);
				String errorMessage = cs.getString(startIndex + 1);

				Map<String, Object> result = new HashMap<String, Object>();
				result.put("status", status);
				result.put("errorMessage", errorMessage);

				return result;

			}
		});

		if (!(Boolean) result.get("status")) {
			throw new SQLException("执行过程[" + synProcName + "[workerOrderNo=" + workerOrderNo + ",orderId=" + orderId
					+ ",remoteId=" + remoteId + "]]发生错误[" + result.get("errorMessage") + "]");
		}

		jdbcTemplate.update("update itf_fa_to_gree_prepare_rule set last_syn_time=? where id=? ",
				new Object[] { updateTime, taskId });

	}

	@Override
	public Long getPgid(String procName, String workerOrderNo, int id) throws Exception {
		return jdbcTemplate.execute(new CallableStatementCreator() {

			public CallableStatement createCallableStatement(Connection con) throws SQLException {

				CallableStatement cs = null;
				cs = con.prepareCall("{call " + procName + "(?,?,?,?,?)}");
				cs.setString(1, workerOrderNo);
				cs.setInt(2, id);
				cs.registerOutParameter(3, Types.BOOLEAN);
				cs.registerOutParameter(4, Types.VARCHAR);
				cs.registerOutParameter(5, Types.BIGINT);

				return cs;
			}
		}, new CallableStatementCallback<Long>() {

			public Long doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {

				cs.execute();

				boolean status = cs.getBoolean(3);
				String errorMessage = cs.getString(4);

				if (!status) {
					throw new SQLException("执行过程[" + procName + "]发生错误[" + errorMessage + "]");
				}

				Long pgid = cs.getLong(5);
				return pgid;

			}
		});
	}

	@Override
	public void refreshSynTime(int taskId, Date updateTime) {
		jdbcTemplate.update("update itf_fa_to_gree_prepare_rule set last_syn_time=? where id=? ",
				new Object[] { updateTime, taskId });

	}

	@Override
	public List<Map<String, Object>> getTaskDataNew() {
		List<Map<String, Object>> result = jdbcTemplate
				.queryForList("SELECT * FROM out_jiasm_to_gree_uploadnotifylist where syn_status=0 order by syn_req_id ");
		return result;
	}
	
	@Override
	public Map<String, Object> getTaskInfo(String srcTabName) {
		Map<String, Object> result = jdbcTemplate.queryForMap("SELECT * FROM out_jiasm_to_gree_prepare_rule where src_tab_name=? ",new Object[] {srcTabName});
		return result;
	}

	@Override
	public void updateSuccess(long reqId) {
		jdbcTemplate.update("UPDATE out_jiasm_to_gree_uploadnotifylist set syn_status=1,syn_time=? where syn_req_id=?",
				new Object[] { new Date(), reqId });
	}

	@Override
	public void updateError(long reqId, String errMessage) {
		if (errMessage != null && errMessage.trim().length() > 255) {
			errMessage = errMessage.substring(0, 255);
		}
		jdbcTemplate.update(
				"UPDATE itf_fa_to_gree_uploadnotifylist set syn_times=syn_times+1, syn_err_msg=?,syn_time=? where syn_req_id=?",
				new Object[] { errMessage, new Date(), reqId });

	}

	@Override
	public Map<String, Object> getTaskDataDetail(String tabName, String orderNo, String id) {
		Map<String, Object> result = new HashMap<>();
		if (tabName.equals("order_base")){
			result = jdbcTemplate.queryForMap(
					"SELECT * FROM " + tabName + " where  id=? ", new Object[] { id });
		} else if (tabName.equals("order_information")){
			result = jdbcTemplate.queryForMap(
					"SELECT * FROM " + tabName + " where order_base_id =? and id=? ", new Object[] { orderNo, id });
		}
		else {
			result = jdbcTemplate.queryForMap(
					"SELECT * FROM " + tabName + " where order_base_id=? and id=? ", new Object[] { orderNo, id });
		}

		return result;
	}

}
