package com.dsk.common.dtos;

import com.dsk.common.exception.BusinessException;
import com.github.pagehelper.PageHelper;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldDefaults;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Getter
@Setter
@FieldDefaults(level=AccessLevel.PRIVATE)
public class Page extends Entity {
	public Page(){
	}

	public Page(Integer page, Integer limit) {
		this.page = page;
		this.limit = limit;
	}

	public Page(List<Map<String, Object>> list, Long total, Integer limit, Integer page){
		this.list = list;
		this.total = total;
		this.page = page;
		this.limit = limit;
	}
	/**
	 * 序列化版本标示
	 */
	private static final long serialVersionUID = 1L;

	// 页码数
	Integer page;
	
	// 单页最大行数
	Integer limit;

	List<?> list;

	String field;

	String order;

	Long total=0L;
	
	@SuppressWarnings("rawtypes")
	private void validateOrderField(boolean isPage, Class cls) {
		if (isPage) {
			PageHelper.startPage(page == null ? 1 : page, limit == null ? 10: limit);
		}
		if (!StringUtils.isEmpty(order) && cls != null&&!StringUtils.isEmpty(field)) {
            String[] orders = this.order.split(",");
            String[] fieldArray = this.field.split(",");
            if (orders.length == fieldArray.length) {
                List<Field> fields = ReflectionUtils.getDeclaredField(cls);
                for (String sort : fieldArray) {
                    boolean isExsit = false;
                    for (Field field : fields) {
                        if (field.getName().equals(sort)) {
                            isExsit = true;
                            break;
                        }
                    }
                    if (!isExsit) {
                        throw new BusinessException("排序字段'{}'异常", sort);
                    }
                }
                StringBuilder orderBy = new StringBuilder();
                for (int i = 0; i < fieldArray.length; i++) {
                    if (i!=0) {
                        orderBy.append(",");
                    }
                    orderBy.append(humpToLine(fieldArray[i])).append(orders[i].equalsIgnoreCase("desc")?" desc":" asc");
                }
                PageHelper.orderBy(orderBy.toString());
            }
        }
	}
	
	public void initPagingData(Class<?> cls){
		this.validateOrderField(true, cls);
	}

	public void initAllData(Class<?> cls){
		this.validateOrderField(false, cls);
	}
	
	public Page setResult(List<?> result){
        com.github.pagehelper.Page<?> page = (com.github.pagehelper.Page<?>) result;
        this.total = page.getTotal();
        this.list = page.getResult();
        return this;
    }
	
	public void setData(List<?> data) {
		this.list = data;
	}

	public static String humpToLine(String str) {
		return str.replaceAll("[A-Z]", "_$0").toLowerCase();
	}

	public List<?> getList() {
		if(CollectionUtils.isEmpty(this.list)){
			this.list = new ArrayList<>();
		}
		return list;
	}

	@Override
	public String toString() {
		return "com.md.common.entity.Page{" +
				"serialVersionUID=" + serialVersionUID +
				", page=" + page +
				", limit=" + limit +
				", list=" + list +
				", field='" + field + '\'' +
				", order='" + order + '\'' +
				", total=" + total +
				'}';
	}
}
