package com.product.data.sync.util;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.product.common.collect.ListUtils;
import com.product.core.dao.BaseDao;
import com.product.core.entity.FieldSetEntity;
import com.product.core.exception.BaseException;
import com.product.core.service.support.AbstractBaseService;
import com.product.data.sync.config.CmnConst;
import com.product.util.BaseUtil;
import com.product.util.CallBack;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.InvocationTargetException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class DataAddDeleteSynchronization extends AbstractBaseService implements Runnable {
    @Autowired
    public ExceptionLog exceptionLog;

    public ExceptionLog getExceptionLog() {
        return exceptionLog;
    }

    public void setExceptionLog(ExceptionLog exceptionLog) {
        this.exceptionLog = exceptionLog;
    }

    @Autowired
    public BaseDao baseDao;

    @Override
    public BaseDao getBaseDao() {
        return baseDao;
    }

    @Override
    public void setBaseDao(BaseDao baseDao) {
        this.baseDao = baseDao;
    }

    private ResultSet resultSet;
    private Map<String, String> map;
    private Map<String, String> syncMap;
    private Map<String, String> sileMap;
    private Map<String, String> deleteMap;
    private CallBack callBack;

    public DataAddDeleteSynchronization(ResultSet resultSet, Map<String, String> map, Map<String, String> sileMap, Map<String, String> syncMap, Map<String, String> deleteMap) {
        this.resultSet = resultSet;
        this.map = map;
        this.syncMap = syncMap;
        this.sileMap = sileMap;
        this.deleteMap = deleteMap;
    }

    public void setCallBack(CallBack callBack) {
        this.callBack = callBack;
    }

    @Override
    public void run() {
        //绯荤粺琛ㄥ悕
        String tableName = map.get("tableName");
        //鏃ュ織uuid
        String logUuid = map.get("logUuid");
        //浜嬩欢鍓嶈皟鐢�
        String savePreEvent = map.get("savePreEvent");
        //浜嬩欢鍚庤皟鐢�
        String postSaveEvent = map.get("postSaveEvent");
        //杩唬鏁伴噺
        Integer resultRow = 0;
        //鏂板鏁伴噺
        Integer addNum = 0;
        //鍒犻櫎鏁伴噺
        Integer deleteNumber = 0;
        //閿欒鏁伴噺
        Integer errorNum = 0;

        List<String> addDataRecord = new ArrayList<>();
        List<String> deleteDataRecord = new ArrayList<>();
        List<String> list = ListUtils.newArrayList();
        while (true) {
            try {
                if (!resultSet.next()) break;
            } catch (SQLException e) {
                exceptionLog.upExceptionLog(logUuid, e);
                break;
            }
            try {
                FieldSetEntity fieldSet = new FieldSetEntity();
                fieldSet.setTableName(tableName);
                resultRow++;
                //鏄惁鏄垹闄ゆ暟鎹�
                Boolean is_delete = false;
                StringBuffer condition = new StringBuffer();
                for (String key : syncMap.keySet()) {
                    fieldSet.setValue(syncMap.get(key), resultSet.getString(key));
                }
                for (String key : deleteMap.keySet()) {
                    //鍒犻櫎楠岃瘉鍊�
                    String deleteValue = map.get("deleteValue");
                    //鍊肩浉鍚屽氨鍒犻櫎鎴栬€呬笉鏂板
                    if (deleteValue.equals(resultSet.getString(key))) {
                        is_delete = true;
                    }
                }
                list.clear();
                for (String key : sileMap.keySet()) {
                    String value = resultSet.getString(key);
                    String fieldName = sileMap.get(key);
                    fieldSet.setValue(fieldName, value);
                    condition.append(fieldName).append(" = ? AND ");
                    list.add(value);
                }
                //璋冪敤淇濆瓨鍓嶆柟娉�
                if (!BaseUtil.strIsNull(savePreEvent) && savePreEvent.indexOf(".") != -1) {
                    DataManipulationUtils.codeCalls(savePreEvent, fieldSet);
                }
                String term = condition.substring(0, condition.length() - 4);
                FieldSetEntity fieldSetEntityByFilter = baseDao.getFieldSetEntityByFilter(tableName, term, list.toArray(new String[]{}), false);

                if (is_delete) {
                    if (fieldSetEntityByFilter != null) {
                        baseDao.delete(tableName, new String[]{fieldSetEntityByFilter.getString(CmnConst.UUID)});
                        deleteDataRecord.add(fieldSetEntityByFilter.getUUID());
                    }
                    deleteNumber++;
                } else {
                    //濡傛灉鏈煡鍒版暟鎹氨鏂板
                    if (fieldSetEntityByFilter == null) {
                        baseDao.add(fieldSet);
                        addDataRecord.add(fieldSet.getUUID());
                        addNum++;
                    } else {
                        errorNum++;
                    }
                }
                //璋冪敤淇濆瓨鍚庢柟娉�
                if (!BaseUtil.strIsNull(postSaveEvent) && postSaveEvent.indexOf(".") != -1) {
                    DataManipulationUtils.codeCalls(postSaveEvent, fieldSet);
                }
            } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | BaseException | SQLException e) {
                errorNum++;
                exceptionLog.addSubExceptionLog(logUuid, list, e);
                continue;
            }
        }
        Map<String, Object> map = Maps.newHashMap();
        //杩唬鏁伴噺
        map.put("resultRow", (resultRow));
        //鏂板鏁伴噺
        map.put("addNum", (addNum));
        //鍒犻櫎鏁伴噺
        map.put("deleteNumber", (deleteNumber));
        //閿欒鏁伴噺
        map.put("errorNum", (errorNum));
        map.put("changeDataKeys", Lists.newArrayList(addDataRecord, null, deleteDataRecord));
        //鍥炶皟鍑芥暟
        if (this.callBack != null) {
            callBack.method(map);
        }
    }
}