package dev.lions.unionflow.server.api.dto.common;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

/**
 * DTO générique pour les réponses paginées de l'API.
 * Utilisé par tous les endpoints REST qui renvoient des données paginées.
 *
 * @param <T> Type des éléments dans la liste
 * @author UnionFlow Team
 * @version 2.0
 */
public class PagedResponse<T> {

    @JsonProperty("data")
    private List<T> data;

    @JsonProperty("total")
    private Long total;

    @JsonProperty("page")
    private Integer page;

    @JsonProperty("size")
    private Integer size;

    @JsonProperty("totalPages")
    private Integer totalPages;

    // Constructeurs
    public PagedResponse() {
    }

    public PagedResponse(List<T> data, Long total, Integer page, Integer size) {
        this.data = data;
        this.total = total;
        this.page = page;
        this.size = size;
        this.totalPages = calculateTotalPages(total, size);
    }

    public PagedResponse(List<T> data, Long total, Integer page, Integer size, Integer totalPages) {
        this.data = data;
        this.total = total;
        this.page = page;
        this.size = size;
        this.totalPages = totalPages;
    }

    // Méthode utilitaire pour calculer le nombre de pages
    private Integer calculateTotalPages(Long total, Integer size) {
        if (size == null || size == 0 || total == null) {
            return 0;
        }
        return (int) Math.ceil((double) total / size);
    }

    // Getters et setters
    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }

    public Long getTotal() {
        return total;
    }

    public void setTotal(Long total) {
        this.total = total;
        this.totalPages = calculateTotalPages(total, this.size);
    }

    public Integer getPage() {
        return page;
    }

    public void setPage(Integer page) {
        this.page = page;
    }

    public Integer getSize() {
        return size;
    }

    public void setSize(Integer size) {
        this.size = size;
        this.totalPages = calculateTotalPages(this.total, size);
    }

    public Integer getTotalPages() {
        return totalPages;
    }

    public void setTotalPages(Integer totalPages) {
        this.totalPages = totalPages;
    }

    // Méthodes utilitaires
    public boolean hasNext() {
        return page != null && totalPages != null && page < totalPages - 1;
    }

    public boolean hasPrevious() {
        return page != null && page > 0;
    }

    public boolean isEmpty() {
        return data == null || data.isEmpty();
    }

    @Override
    public String toString() {
        return "PagedResponse{" +
                "total=" + total +
                ", page=" + page +
                ", size=" + size +
                ", totalPages=" + totalPages +
                ", itemsCount=" + (data != null ? data.size() : 0) +
                '}';
    }
}
