/* (C) 2021 YiRing, Inc. */
package com.yiring.common.param;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import java.io.Serial;
import java.io.Serializable;
import java.util.Objects;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;
import lombok.experimental.SuperBuilder;
import org.hibernate.validator.constraints.Range;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

/**
 * 公共的分页排序查询参数
 * eg: 支持使用 @Validated(Group.Optional.class) 来忽略校验
 *
 * @author ifzm
 * @version 0.1 2019/3/10 16:29
 */
@Schema(name = "PageParam", description = "公共的分页排序查询参数")
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class PageParam implements Serializable {

    @Serial
    private static final long serialVersionUID = 6103761701912769946L;

    @Schema(description = "分页条数", defaultValue = "10", example = "10", type = "integer")
    @NotNull
    @Range(min = 1, max = 100)
    Integer pageSize;

    @Schema(description = "当前页数", defaultValue = "1", example = "1", type = "integer")
    @NotNull
    @Min(1)
    Integer pageNo;

    @Schema(description = "排序字段", defaultValue = "id", example = "id")
    String sortField;

    @Schema(description = "排序方向（ASC|DESC）", defaultValue = "DESC", example = "DESC")
    Sort.Direction sortOrder;

    /**
     * 根据参数构建分页对象
     *
     * @param param {@link PageParam}
     * @return Pageable
     */
    @SuppressWarnings({ "unused" })
    public static Pageable toPageable(PageParam param) {
        if (param == null || Objects.isNull(param.getPageNo()) || Objects.isNull(param.getPageSize())) {
            return Pageable.unpaged();
        }

        return PageParam.toPageable(param.getSortField(), param.getSortOrder(), param.getPageSize(), param.getPageNo());
    }

    /**
     * 根据参数构建分页对象
     *
     * @param sortField 排序字段
     * @param sortOrder 排序方向
     * @param pageSize  分页大小
     * @param pageNo    分页页码
     * @return Pageable
     */
    public static Pageable toPageable(String sortField, Sort.Direction sortOrder, Integer pageSize, Integer pageNo) {
        Sort sort = Sort.unsorted();
        if (Objects.nonNull(sortField)) {
            sort = Sort.by(new Sort.Order(sortOrder, sortField));
        }
        return PageRequest.of(pageNo - 1, pageSize, sort);
    }
}
