package com.zcxk.core.mongo.pageing;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;

import java.io.Serializable;

/**
 * mongodb分类组件实现类
 */
/**
 * @author Andy
 * @date 2021-07-22 11:03
 */
public class PageableImpl implements Pageable, Serializable {

    private static final long serialVersionUID = -2348915232521382937L;

    private int page = 1;

    private int size = 10;

    private Sort sort;

    public PageableImpl() {

    }

    public static PageableImpl get() {
        return new PageableImpl();
    }

    public PageableImpl(int page, int size) {
        this(page, size, null);
    }

    public PageableImpl(Direction direction, String... properties) {
        this(1, 10, new Sort(direction, properties));
    }

    public PageableImpl(int page, int size, Direction direction, String... properties) {
        this(page, size, new Sort(direction, properties));
    }

    public PageableImpl(int page, int size, Sort sort) {

        if (0 > page) {
            throw new IllegalArgumentException("Page index must not be less than zero!");
        }

        if (0 >= size) {
            throw new IllegalArgumentException("Page size must not be less than or equal to zero!");
        }

        this.page = page;
        this.size = size;
        this.sort = sort;
    }

    @Override
    public int getPageNumber() {
        return page;
    }

    @Override
    public int getPageSize() {
        return size;
    }

    @Override
    public long getOffset() {
        return (page - 1) * size;
    }

    @Override
    public Sort getSort() {
        return sort;
    }

    @Override
    public boolean equals(final Object obj) {

        if (this == obj) {
            return true;
        }

        if (!(obj instanceof PageRequest)) {
            return false;
        }

        PageableImpl that = (PageableImpl) obj;

        boolean pageEqual = this.page == that.page;
        boolean sizeEqual = this.size == that.size;

        boolean sortEqual = this.sort == null ? that.sort == null : this.sort.equals(that.sort);

        return pageEqual && sizeEqual && sortEqual;
    }

    @Override
    public int hashCode() {

        int result = 17;

        result = 31 * result + page;
        result = 31 * result + size;
        result = 31 * result + (null == sort ? 0 : sort.hashCode());

        return result;
    }

    @Override
    public String toString() {
        return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
    }

    @Override
    public Pageable next() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Pageable previousOrFirst() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Pageable first() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean hasPrevious() {
        // TODO Auto-generated method stub
        return false;
    }
}
