package com.keyware.shandan.dynacmicform.core.basic.entity;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.keyware.shandan.common.util.StringUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Data
@EqualsAndHashCode(callSuper = true)
public class QueryParam extends LinkedHashMap<String, QueryParam.Param> {

    private static final long serialVersionUID = -4759922534007993343L;

    private Integer page = 0;
    private Integer pageSize = 30;

    private String orderField;
    private String orderType = "ASC";

    /**
     * 返回一个查询参数构建器
     *
     * @return 查询参数构建器
     */
    public static QueryParamBuilder builder() {
        return new QueryParamBuilder();
    }

    /**
     * 从Json字符串中解析出查询参数对象
     *
     * @param jsonText JSON字符串
     * @return 查询参数对象
     */
    public static QueryParam parse(String jsonText) {
        JSONArray jsonArray = JSONArray.parseArray(jsonText);
        QueryParamBuilder builder = builder();
        if (jsonArray != null) {
            jsonArray.forEach(obj -> {
                JSONObject json = (JSONObject) obj;
                builder.column(json.getString("column"))
                        .logic(json.getString("logic"))
                        .value(json.get("value"));
            });
        }
        return builder.build();
    }


    /**
     * 解析排序參數
     *
     * @param order
     */
    public void parseOrder(String order) {
        if (StringUtils.hasText(order)) {
            JSONObject json = null;
            try {
                json = JSON.parseObject(order);
            } catch (Exception e) {
                log.error("动态数据查询，排序参数解析失败", e);
            }
            if (json != null) {
                orderField = json.getString("field");
                orderType = json.getString("type");
            }
        }
    }

    public String getOrderSqlSegment() {
        if (StringUtils.hasText(orderField) && StringUtils.hasText(orderType)) {
            return "ORDER BY \"" + orderField + "\" " + orderType;
        }
        return "";
    }

    /**
     * 获取参数集的值
     *
     * @return 值的集合
     */
    public List<Object> getParamValues() {
        return values().stream().map(Param::getValue).collect(Collectors.toList());
    }

    /**
     * 获取用and拼接的Sql片段
     *
     * @return sql片段
     */
    public String getSqlSegment() {
        List<String> likeSqlFragment = new ArrayList<>();
        List<String> sqlFragment = new ArrayList<>();
        this.values().forEach(param -> {
            if (param.getLogic() == LogicSymbol.like
                    || param.getLogic() == LogicSymbol.likeRight
                    || param.getLogic() == LogicSymbol.likeLeft) {
                likeSqlFragment.add(param.getSqlFragment());
            } else {
                sqlFragment.add(param.getSqlFragment());
            }
        });

        String sql = " WHERE 1 = 1 ";
        if(likeSqlFragment.size() > 0){
            sql += " AND ( " + String.join(" OR ", likeSqlFragment) + " ) ";
        }
        if (sqlFragment.size() > 0) {
            sql += " AND ( " + String.join(" AND ", sqlFragment) + " )";
        }
        return sql;
    }

    /**
     * 查询参数子类
     */
    @Data
    public static class Param {
        /**
         * 参数查询的列名
         */
        private String column;
        /**
         * 查询条件的判断符合 = 、!= 、> 、 <、like
         */
        private LogicSymbol logic;
        /**
         * 条件参数的值
         */
        private Object value;

        public String getSqlFragment() {
            String col = "\"" + column + "\" ";
            switch (logic) {
                case lt:
                case gt:
                case le:
                case ge:
                case eq:
                case ne:
                case like:
                case likeLeft:
                case likeRight:
                    return col + logic.value;
                case in:
                case notIn:
                    String val = (String) value;
                    if (val.contains(",")) {
                        // 将所有的值替换为占位符?
                        List<String> temp = Arrays.stream(val.split(",")).map(v -> "?").collect(Collectors.toList());
                        val = String.join(",", temp);
                    } else {
                        val = "?";
                    }
                    return col + logic.value.replace("...?", val);
                default:
                    return "";
            }
        }
    }

    @Getter
    @AllArgsConstructor
    public enum LogicSymbol {
        lt("< ?"),
        gt("> ?"),
        le("<= ?"),
        ge(">= ?"),
        eq("= ?"),
        ne("<> ?"),
        like("like CONCAT('%', ?, '%')"),
        likeLeft("like CONCAT('%', ?)"),
        likeRight("like CONCAT(?, '%')"),
        in("in (...?)"),
        notIn("not in(...?)");

        // 判定符号
        private final String value;
    }
}
