package com.bonus.canteen.core.common.page;

import com.github.pagehelper.Page;

import java.util.Collections;
import java.util.List;

public class PageVO<T> {
   protected List<T> records;
   protected long total;
   protected long size;
   protected long current;
   protected boolean searchCount;
   private String orderBy;

   public PageVO() {
      this.records = Collections.emptyList();
      this.total = 0L;
      this.size = 10L;
      this.current = 1L;
      this.searchCount = true;
   }

   public PageVO(long current, long size) {
      this(current, size, 0L);
   }

   public PageVO(long current, long size, long total) {
      this(current, size, total, true);
   }

   public PageVO(long current, long size, boolean searchCount) {
      this(current, size, 0L, searchCount);
   }

   public PageVO(long current, long size, long total, boolean searchCount) {
      this.records = Collections.emptyList();
      this.total = 0L;
      this.size = 10L;
      this.current = 1L;
      this.searchCount = true;
      if (current > 1L) {
         this.current = current;
      }

      this.size = size;
      this.total = total;
      this.searchCount = searchCount;
   }

   public static <T> PageVO<T> empty() {
      return new PageVO();
   }

   public static <T> PageVO<T> of(long current, long size, long total, boolean searchCount) {
      return new PageVO(current, size, total, searchCount);
   }

   public static <T> PageVO<T> of(long current, long size) {
      return of(current, size, 0L);
   }

   public static <T> PageVO<T> of(long current, long size, long total) {
      return of(current, size, total, true);
   }

   public static <T> PageVO<T> of(long current, long size, boolean searchCount) {
      return of(current, size, 0L, searchCount);
   }

   public static <T> PageVO<T> of(List<?> page, List<T> records) {
      if (page instanceof Page) {
         PageVO<T> vo = of((long)((Page)page).getPageNum(), (long)((Page)page).getPageSize(), ((Page)page).getTotal(), ((Page)page).isCount());
         vo.setOrderBy(((Page)page).getOrderBy());
         vo.setRecords(records);
         return vo;
      } else {
         return of(records);
      }
   }

   public static <T> PageVO<T> of(List<T> records) {
      PageVO<T> vo = new PageVO();
      vo.setRecords(records);
      if (records instanceof Page) {
         Page<T> ghRecords = (Page<T>) records;
         vo.setCurrent((long)ghRecords.getPageNum()).setSize((long)ghRecords.getPageSize()).setTotal(ghRecords.getTotal()).setSearchCount(ghRecords.isCount()).setOrderBy(vo.getOrderBy());
      }

      return vo;
   }

   public static <T> PageVO<T> of(PageDTO pageDTO, List<T> records) {
      PageVO<T> vo = new PageVO();
      vo.setRecords(records);
      if (records instanceof Page) {
         Page<T> ghRecords = (Page<T>) records;
         vo.setCurrent((long)ghRecords.getPageNum()).setSize((long)ghRecords.getPageSize()).setTotal(ghRecords.getTotal()).setSearchCount(ghRecords.isCount()).setOrderBy(vo.getOrderBy());
      } else if (records != null) {
         vo.setCurrent(pageDTO.getCurrent()).setSize(pageDTO.getSize()).setTotal((long)records.size()).setOrderBy(pageDTO.getOrderBy());
      }

      return vo;
   }

   public static <T> PageVO<T> of(com.baomidou.mybatisplus.extension.plugins.pagination.Page<T> page) {
      if (page == null) {
         return new PageVO();
      } else {
         PageVO<T> vo = of(page.getCurrent(), page.getSize(), page.getTotal(), page.searchCount());
         vo.setRecords(page.getRecords());
         return vo;
      }
   }

   public static <T> PageVO<T> of(com.baomidou.mybatisplus.extension.plugins.pagination.Page<?> page, List<T> records) {
      if (page == null) {
         return new PageVO();
      } else {
         PageVO<T> vo = of(page.getCurrent(), page.getSize(), page.getTotal(), page.searchCount());
         vo.setRecords(records);
         return vo;
      }
   }

   public boolean hasPrevious() {
      return this.current > 1L;
   }

   public boolean hasNext() {
      return this.current < this.getPages();
   }

   public List<T> getRecords() {
      return this.records;
   }

   public PageVO<T> setRecords(List<T> records) {
      this.records = records;
      return this;
   }

   public long getTotal() {
      return this.total;
   }

   public PageVO<T> setTotal(long total) {
      this.total = total;
      return this;
   }

   public long getSize() {
      return this.size;
   }

   public PageVO<T> setSize(long size) {
      this.size = size;
      return this;
   }

   public long getCurrent() {
      return this.current;
   }

   public PageVO<T> setCurrent(long current) {
      this.current = current;
      return this;
   }

   public PageVO<T> setSearchCount(boolean searchCount) {
      this.searchCount = searchCount;
      return this;
   }

   public String getOrderBy() {
      return this.orderBy;
   }

   public PageVO<T> setOrderBy(String orderBy) {
      this.orderBy = orderBy;
      return this;
   }

   public long getPages() {
      if (this.getSize() == 0L) {
         return 0L;
      } else {
         long pages = this.getTotal() / this.getSize();
         if (this.getTotal() % this.getSize() != 0L) {
            ++pages;
         }

         return pages;
      }
   }

   public boolean searchCount() {
      return this.total < 0L ? false : this.searchCount;
   }
}
