package com.boman.web.core.domain;

import com.alibaba.fastjson.JSONObject;
import com.boman.common.core.utils.SpringUtils;
import com.boman.common.redis.RedisKey;
import com.boman.common.redis.service.RedisService;
import com.boman.domain.GenTable;
import com.boman.domain.GenTableColumn;
import com.boman.web.core.utils.IdUtils;

import java.util.List;
import java.util.Map;

import static com.boman.common.core.utils.obj.ObjectUtils.ltZero;
import static com.boman.common.core.utils.obj.ObjectUtils.requireNonNull;
import static com.boman.domain.constant.MaskConstant.*;
import static com.boman.web.core.utils.ColumnUtils.withoutHr;

/**
 * @author shiqian
 * @date 2021年04月13日 11:07
 **/
public class TableContext {

    private Long id;
    private String pkName;
    private GenTable table;
    private ActionType actionType;
    private String tableName;
    private JSONObject fixedData;
    private JSONObject commitData;
    private List<GenTableColumn> columns;

    public static TableContext createContext(FormDataDto dto) {
        TableContext context = new TableContext();
        context.setId(dto.getObjId());
        String tableName = requireNonNull(dto.getTable(), "tableName is empty");
        context.setTableName(tableName);

        RedisService redisService = SpringUtils.getBean(RedisService.class);
        GenTable table = redisService.getCacheObject(RedisKey.TABLE_INFO + tableName);
        context.setTable(requireNonNull(table, "redis中没有此表，表名: " + tableName));

        List<GenTableColumn> columns = table.getColumns();
        context.setColumns(columns);

        String pkName = IdUtils.getPkName(columns);
        context.setPkName(pkName);

        JSONObject fixedData = requireNonNull(dto.getFixedData(), "fixedData is empty");
        context.setFixedData(fixedData);

        JSONObject commitData = new JSONObject();
        packCommitData(dto.getObjId(), context, columns, fixedData, commitData);
        context.setCommitData(commitData);

        return context;

    }


    private static void packCommitData(Long objId, TableContext context, List<GenTableColumn> columns
            , JSONObject fixedData, JSONObject commitData) {
        boolean isInsert = ltZero(objId);
        context.setActionType(isInsert ? ActionType.INSERT : ActionType.UPDATE);
        // 过滤掉hr字段
        columns = withoutHr(columns);
        for (GenTableColumn column : columns) {
            String[] maskArray = requireNonNull(column.getMask(), "mask is empty, columnName = " + column.getColumnName()).split("");
            assert maskArray.length == 6;
            // 新增可见 修改可见
            String insertVisible = maskArray[0], updateVisible = maskArray[2];
            // 新增可修改 修改可修改
            String insertCanEdit = maskArray[1], updateCanEdit = maskArray[3];
            for (Map.Entry<String, Object> entry : fixedData.entrySet()) {
                if (column.getColumnName().equalsIgnoreCase(entry.getKey())) {
                    // 新增
                    if (isInsert) {
                        // 新增可修改, 并且新增可见，把新增的字段单独拿出来
                        if (INSERT_CAN_EDIT.equals(insertCanEdit) && INSERT_VISIBLE.equals(insertVisible)) {
                            commitData.put(entry.getKey(), entry.getValue());
                        } else {
                            // ignore
                        }
                    } else {
                        // 编辑可修改, 并且编辑可见
                        if (UPDATE_CAN_EDIT.equals(updateCanEdit) && UPDATE_VISIBLE.equals(updateVisible)) {
                            commitData.put(entry.getKey(), entry.getValue());
                        } else {
                            // ignore
                        }
                    }
                }
            }
        }
    }


    /**                 get and set                               **/

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getPkName() {
        return pkName;
    }

    public void setPkName(String pkName) {
        this.pkName = pkName;
    }

    public GenTable getTable() {
        return table;
    }

    public void setTable(GenTable table) {
        this.table = table;
    }

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public JSONObject getFixedData() {
        return fixedData;
    }

    public void setFixedData(JSONObject fixedData) {
        this.fixedData = fixedData;
    }

    public JSONObject getCommitData() {
        return commitData;
    }

    public void setCommitData(JSONObject commitData) {
        this.commitData = commitData;
    }

    public List<GenTableColumn> getColumns() {
        return columns;
    }

    public void setColumns(List<GenTableColumn> columns) {
        this.columns = columns;
    }

    public ActionType getActionType() {
        return actionType;
    }

    public void setActionType(ActionType actionType) {
        this.actionType = actionType;
    }
}
