package com.ruoyi.system.util;

import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class PaginationUtil {

    /**
     * 通用分页方法
     */
    public static <T> PageInfo<T> paginate(List<T> dataList, int pageNum, int pageSize) {
        if (dataList == null) {
            dataList = new ArrayList<>();
        }

        int total = dataList.size();

        // 计算分页参数
        int totalPages = calculateTotalPages(total, pageSize);
        pageNum = validatePageNum(pageNum, totalPages);

        // 分页数据
        List<T> pageData = getPageData(dataList, pageNum, pageSize);

        return buildPageInfo(pageData, pageNum, pageSize, total, totalPages);
    }

    /**
     * 带排序的分页
     */
    public static <T> PageInfo<T> paginateWithSort(
            List<T> dataList,
            int pageNum,
            int pageSize,
            Comparator<T> comparator) {

        if (dataList == null) {
            dataList = new ArrayList<>();
        }

        // 先排序
        List<T> sortedList = dataList.stream()
                .sorted(comparator)
                .collect(Collectors.toList());

        return paginate(sortedList, pageNum, pageSize);
    }

    private static int calculateTotalPages(int total, int pageSize) {
        if (pageSize <= 0) {
            return 0;
        }
        return (int) Math.ceil((double) total / pageSize);
    }

    private static int validatePageNum(int pageNum, int totalPages) {
        if (pageNum < 1) {
            return 1;
        }
        if (totalPages > 0 && pageNum > totalPages) {
            return totalPages;
        }
        return pageNum;
    }

    private static <T> List<T> getPageData(List<T> dataList, int pageNum, int pageSize) {
        int fromIndex = (pageNum - 1) * pageSize;
        if (fromIndex >= dataList.size()) {
            return new ArrayList<>();
        }

        int toIndex = Math.min(fromIndex + pageSize, dataList.size());
        return dataList.subList(fromIndex, toIndex);
    }

    private static <T> PageInfo<T> buildPageInfo(List<T> data, int pageNum, int pageSize,
                                                 int total, int totalPages) {
        PageInfo<T> pageInfo = new PageInfo<>();
        pageInfo.setList(data);
        pageInfo.setPageNum(pageNum);
        pageInfo.setPageSize(pageSize);
        pageInfo.setTotal((long) total);
        pageInfo.setPages(totalPages);
        pageInfo.setHasNextPage(pageNum < totalPages);
        pageInfo.setHasPreviousPage(pageNum > 1);
        pageInfo.setIsFirstPage(pageNum == 1);
        pageInfo.setIsLastPage(pageNum == totalPages || totalPages == 0);

        return pageInfo;
    }
}