package org.nl.common.domain.query;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Locale;


/**
 * 分页参数
 */
@Data
public class PageQuery implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 分页大小
     */
    private Integer size;

    /**
     * 当前页数
     */
    private Integer page;

    /**
     * 排序列
     */
    private String sort;

    /**
     * 排序的方向desc或者asc
     */
    private Boolean isAsc;

    /**
     * 当前记录起始索引 默认值
     */
    public static final int DEFAULT_PAGE_NUM = 1;

    /**
     * 每页显示记录数 默认值 默认查全部
     */
    public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE;

    public <T> Page<T> build() {
        Integer pageNum = ObjectUtil.defaultIfNull(getPage(), DEFAULT_PAGE_NUM);
        Integer pageSize = ObjectUtil.defaultIfNull(getSize(), DEFAULT_PAGE_SIZE);
        if (pageNum <= 0) {
            pageNum = DEFAULT_PAGE_NUM;
        }
        Page<T> page = new Page<>(pageNum, pageSize);
        if (StringUtils.isNotEmpty(sort)){
            String[] split = sort.split(",");
            for (int i = 0; i < (split.length & ~1); i=i+2) {
                String col = split[i];
                OrderItem item = new OrderItem();
                item.setColumn(col);
                item.setAsc(split[i+1].toLowerCase(Locale.ROOT).equals("asc"));
                page.addOrder(item);
            }
        }
        return page;
    }

    public <R,T> Page<T> build(Class<R> r) {
        Integer pageNum = ObjectUtil.defaultIfNull(getPage(), DEFAULT_PAGE_NUM);
        Integer pageSize = ObjectUtil.defaultIfNull(getSize(), DEFAULT_PAGE_SIZE);
        if (pageNum <= 0) {
            pageNum = DEFAULT_PAGE_NUM;
        }
        Page<T> page = new Page<>(pageNum, pageSize);
        if (StringUtils.isNotEmpty(sort)){
            String[] split = sort.split(",");
            for (int i = 0; i < (split.length & ~1); i=i+2) {
                String col = split[i];
                if ("id".equals(col)){
                    String mId = mappingId(r);
                    col = StringUtils.isNotEmpty(mId)?mId:col;
                }
                OrderItem item = new OrderItem();
                item.setColumn(col);
                item.setAsc(split[i+1].toLowerCase(Locale.ROOT).equals("asc"));
                page.addOrder(item);
            }

        }
        return page;
    }

    private <R> String mappingId(R r){
        if (r instanceof Class){
            Field[] fields = ((Class) r).getDeclaredFields();
            for (Field field : fields) {
                TableId[] byType = field.getAnnotationsByType(TableId.class);
                if (byType !=null && byType.length>0){
                    TableId tableId = byType[0];
                    return tableId.value();
                }
            }
        }
        return null;
    }
}
