package com.iformall.domain.po.base;

import com.baomidou.mybatisplus.annotation.TableField;
import com.iformall.common.SortColumn;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author luozukai
 * @date 2019/4/24 14:32
 */
@Data
@Slf4j
public class BaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableField(exist = false)
    private List<Long> ids;

    @TableField(exist = false)
    private String sortColumn;

    @TableField(exist = false)
    private String sortOrder;

    @TableField(exist = false)
    private String sortColumns;

    @TableField(exist = false)
    protected String floorForRule;

    @TableField(exist = false)
    protected String businessForRule;

    @TableField(exist = false)
    protected String[] tempShop;

    public String getSortColumns() {
        if(StringUtils.isBlank(sortColumn)){
            return sortColumns;
        }

        try {
            //扫描子类SortColumn注解的属性,替换sortColumn
            if(StringUtils.isNotBlank(sortColumn)) {
                List<Field> fieldList = new ArrayList<>() ;
                Class tempClass = this.getClass();
                while (tempClass != null) {//当父类为null的时候说明到达了最上层的父类(Object类).
                    fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields()));
                    tempClass = tempClass.getSuperclass(); //得到父类,然后赋给自己
                }

                //扫描注解，优先解析注解
                for (Field field : fieldList) {
                    SortColumn sortColumnField = field.getAnnotation(SortColumn.class);
                    if (sortColumnField != null && field.getName().equals(sortColumn)) {
                        return sortColumnField.column() + " "+sortOrder;
                    }
                }

                //判断是否合法
                boolean find = false;
                for (Field field : fieldList){
                    if (field.getName().equals(sortColumn)) {
                        find = true;
                        break;
                    }
                }
                if(!find) {
                    return null;
                }

                //默认驼峰解析
                return underscoreName(sortColumn) +" "+sortOrder;
            }
        } catch (Exception e) {
            log.error("BaseEntity.getSortColumn解析失败",e);
            e.printStackTrace();
        }
        return sortColumns;
    }

    /**
     * 转换为下划线
     *
     * @param camelCaseName
     * @return
     */
    private static String underscoreName(String camelCaseName) {
        StringBuilder result = new StringBuilder();
        if (camelCaseName != null && camelCaseName.length() > 0) {
            result.append(camelCaseName.substring(0, 1).toLowerCase());
            for (int i = 1; i < camelCaseName.length(); i++) {
                char ch = camelCaseName.charAt(i);
                if (Character.isUpperCase(ch)) {
                    result.append("_");
                    result.append(Character.toLowerCase(ch));
                } else {
                    result.append(ch);
                }
            }
        }
        return result.toString();
    }

    public void setSortColumns(SortField... fields)
    {
        if (fields == null || fields.length == 0) {
            return;
        }
        for (int k = 0; k < fields.length; k++) {
            if (fields[k] == null) {
                return;
            }
        }
        StringBuilder sb = new StringBuilder(fields[0].toString());
        for (int k = 1; k < fields.length; k++) {
            sb.append(",");
            sb.append(fields[k].toString());
        }
        this.sortColumns=sb.toString();

    }

    public enum SortField {
        Id_ASC("`id` ASC"),
        Id_DESC("`id` DESC"),

        CreateDate_ASC("`create_date` ASC"),
        CreateDate_DESC("`create_date` DESC"),

        UpdateDate_ASC("`update_date` ASC"),
        UpdateDate_DESC("`update_date` DESC"),

        Createtime_ASC("`createtime` ASC"),
        Createtime_DESC("`createtime` DESC"),

        CreateTime_ASC("`create_time` ASC"),
        CreateTime_DESC("`create_time` DESC"),

        ReportTime_ASC("`reportTime` ASC"),
        ReportTime_DESC("`reportTime` DESC"),

        ActiveTime_ASC("`active_time` ASC"),
        ActiveTime_DESC("`active_time` DESC"),

        TopTime_ASC("`top_time` ASC"),
        TopTime_DESC("`top_time` DESC"),

        MerchantId_ASC("`merchant_id` ASC"),
        MerchantId_DESC("`merchant_id` DESC"),

        LimitDate_ASC("`limit_date` ASC"),
        LimitDate_DESC("`limit_date` DESC"),

        SortNum_ASC("`sort_num` ASC"),
        SortNum_DESC("`sort_num` DESC"),

        Sort_ASC("`sort` ASC"),
        Sort_DESC("`sort` DESC"),

        Points_ASC("`points` ASC"),
        Points_DESC("`points` DESC"),

        Period_ASC("`period` ASC"),
        Period_DESC("`period` DESC"),

        UsedPower_ASC("`usedPower` ASC"),
        UsedPower_DESC("`usedPower` DESC"),

        Date_ASC("`date` ASC"),
        Date_DESC("`date` DESC"),

        TradeAmt_ASC("`trade_amt` ASC"),
        TradeAmt_DESC("`trade_amt` DESC"),

        ReportDate_ASC("`report_date` ASC"),
        ReportDate_DESC("`report_date` DESC"),
        ;
        
        private String value;

        SortField(String value) {
            this.value = value;
        }
        public String getValue() {
            return value;
        }
        @Override
        public String toString() {
            return this.getValue();
        }
    }


}
