package base

import (
	"fmt"
	"strings"
)

type IPage interface {
	GetTotal() int64             //获取总记录数
	SetTotal(int64)              //设置总记录数
	GetCurrent() int64           //获取当前页
	SetCurrent(int64)            //设置当前页
	GetPageSize() int64          //获取每页显示大小
	SetPageSize(int64)           //设置每页显示大小
	AddOrderItem(OrderItem)      // 设置排序条件
	AddOrderItems([]OrderItem)   // 批量设置排序条件
	GetOrderItemsString() string // 将排序条件拼接成字符串
	Offset() int64               // 获取偏移量
	GetPages() int64             // 获取总的分页数
}

type OrderItem struct {
	Column string // 需要排序的字段
	Asc    bool   // 是否正序排列,默认true
}

type BaseData struct {
	Page *Page        `json:"page"`
	List interface{} `json:"list"` // 查询数据列表
}

type BaseOnlyData struct {
	List interface{} `json:"list"` // 查询数据列表
}

type Page struct {
	Total    int64       `json:"total"`     // 总的记录数
	Pages    int64       `json:"pages"`     //总页数
	PageSize int64       `json:"page_size"` // 每页显示的大小
	Current  int64       `json:"current"`   // 当前页
	orders   []OrderItem `json:"orders"`    // 排序条件
}

type PageReq struct {
	PageSize int64 `json:"page_size" form:"page_size,default=20"`
	Current  int64 `json:"current" form:"current,default=1"`
}

func (b *BaseData) GetList() interface{} {
	return b.List
}

func (b *BaseData) SetList(list interface{}) {
	b.List = list
}


func (bo *BaseOnlyData) GetList() interface{} {
	return bo.List
}

func (bo *BaseOnlyData) SetList(list interface{}) {
	bo.List = list
}

func (b *BaseData) GetPage() *Page {
	return b.Page
}
func (b *BaseData) SetPage(page *Page) {
	b.Page = page
}

func (page *Page) GetTotal() int64 {
	return page.Total
}

func (page *Page) SetTotal(total int64) {
	page.Total = total
	page.SetPages()
}

func (page *Page) GetCurrent() int64 {
	return page.Current
}

func (page *Page) SetCurrent(current int64) {
	page.Current = current
}

func (page *Page) GetPageSize() int64 {
	return page.PageSize
}
func (page *Page) SetPageSize(size int64) {
	page.PageSize = size
}

func (page *Page) AddOrderItem(orderItem OrderItem) {
	page.orders = append(page.orders, orderItem)
}

func (page *Page) AddOrderItems(orderItems []OrderItem) {
	page.orders = append(page.orders, orderItems...)
}

func (page *Page) GetOrderItemsString() string {
	arr := make([]string, 0)
	var order string

	for _, val := range page.orders {
		if val.Asc {
			order = ""
		} else {
			order = "desc"
		}
		arr = append(arr, fmt.Sprintf("%s %s", val.Column, order))
	}
	return strings.Join(arr, ",")
}

func (page *Page) Offset() int64 {
	if page.GetCurrent() > 0 {
		return (page.GetCurrent() - 1) * page.GetPageSize()
	} else {
		return 0
	}
}

func (page *Page) GetPages() int64 {
	if page.GetPageSize() == 0 {
		return 0
	}
	pages := page.GetTotal() / page.GetPageSize()
	if page.GetTotal()%page.PageSize != 0 {
		pages++
	}

	return pages
}

func (page *Page) SetPages() {
	if page.GetPageSize() == 0 {
		page.Pages = 0
	} else {
		pages := page.GetTotal() / page.GetPageSize()
		if page.GetTotal()%page.PageSize != 0 {
			pages++
		}
		page.Pages = pages
	}
}

func BuildAsc(column string) OrderItem {
	return OrderItem{Column: column, Asc: true}
}

func BuildDesc(column string) OrderItem {
	return OrderItem{Column: column, Asc: false}
}

func BuildAscs(columns ...string) []OrderItem {
	items := make([]OrderItem, 0)
	for _, val := range columns {
		items = append(items, BuildAsc(val))
	}
	return items
}

func BuildDescs(columns ...string) []OrderItem {
	items := make([]OrderItem, 0)
	for _, val := range columns {
		items = append(items, BuildDesc(val))
	}
	return items
}

func NewPage(pageSize, current int64, orderItems ...OrderItem) *Page {
	return &Page{PageSize: pageSize, Current: current, orders: orderItems}
}