package cn.com.smart.form.list;

import cn.com.smart.form.FormConstants;
import cn.com.smart.report.service.IReportSqlResourceCallback;
import com.mixsmart.utils.LoggerUtils;
import com.mixsmart.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
public class SortingSqlResourceCallback implements IReportSqlResourceCallback {

    private static final Logger logger = LoggerFactory.getLogger(SortingSqlResourceCallback.class);

    @Override
    public String callback(String sql, Map<String, Object> param) {
        String sortField = StringUtils.handleNull(param.get(FormConstants.LIST_FORM_SORT_FIELD));
        String sorting = StringUtils.handleNull(param.get(FormConstants.LIST_FORM_SORTING));
        param.remove(FormConstants.LIST_FORM_SORT_FIELD);
        param.remove(FormConstants.LIST_FORM_SORTING);
        if(StringUtils.isEmpty(sortField)) {
            return sql;
        }
        if(StringUtils.isEmpty(sorting)) {
            sorting = FormConstants.SORTING_ASC;
        } else if(!(sorting.equals(FormConstants.SORTING_ASC) ||
                sorting.equals(FormConstants.SORTING_DESC))) {
            sorting = FormConstants.SORTING_ASC;
        }
        String handleSortField = getFieldAlias(sql, sortField);
        sql = handleSortSql(sql, handleSortField, sorting);
        return sql;
    }

    /**
     * 判断排序字段上是否有别名
     * @param sortField 字段名称（可能会包含别名）
     * @return 如果包含别名则返回true；否则返回false
     */
    private boolean isHasAlias(String sortField) {
        if(StringUtils.isEmpty(sortField)) {
            return false;
        }
        return sortField.indexOf(".") > -1;
    }

    /**
     * 获取字段别名
     * @param sql
     * @param sortField
     * @return
     */
    private String getFieldAlias(String sql, String sortField) {
        if(isHasAlias(sortField)) {
            return "";
        }
        String findField = "." + sortField+" ";
        int index = sql.indexOf(findField);
        if(index == -1) {
            return "";
        }
        int prevIndex = sql.lastIndexOf(" ", index);
        if(prevIndex == -1) {
            LoggerUtils.warn(logger, "获取别名失败，有可能是SQL预计的问题，SQL语句为:[].", sql);
            return "";
        }
        String alias = sql.substring(prevIndex+1, index);
        int commaIndex= alias.lastIndexOf(",");
        if(commaIndex > -1) {
            alias = alias.substring(commaIndex + 1);
        }
        return alias + "." + sortField;
    }

    /**
     * 处理排序的SQL语句
     * @param sql
     * @param sortField
     * @param sorting
     * @return
     */
    private String handleSortSql(String sql, String sortField, String sorting) {
        //判断SQL语句中是否有order by 关键字
        String handleSql = sql;
        handleSql = handleSql.toLowerCase();
        int index = handleSql.lastIndexOf(" order by ");
        if(index == -1) {
            sql = sql + " order by " + sortField + " " + sorting;
        } else {
            handleSql = handleSql.trim();
            String orderBy = handleSql.substring(index);
            //判断orderBy是否是子语句
            if(orderBy.contains(")") || orderBy.contains(" where ") ||
                    orderBy.contains(" and ") || orderBy.contains(" select ")) {
                sql = sql + " order by " + sortField + " " + sorting;
            } else {
                sql = sql + "," + sortField + " " + sorting;
            }
        }
        return sql;
    }
}
