package com.cym.bean;

import java.util.ArrayList;
import java.util.List;

import com.cym.bean.OrderBy.Direction;
import com.cym.reflection.ReflectionUtil;
import com.cym.reflection.SerializableFunction;
import cn.hutool.core.util.StrUtil;

public class Sort {
	List<OrderBy> orderList = new ArrayList<>();

	public Sort() {

	}

	public Sort(String column, Direction direction) {
		OrderBy order = new OrderBy();
		order.setColumn(column);
		order.setDirection(direction);

		orderList.add(order);
	}

	public Sort(List<OrderBy> orderList) {
		this.orderList.addAll(orderList);
	}

	public Sort(String orderByStr) {
		OrderBy order = new OrderBy();
		order.setOrderByStr(orderByStr);

		orderList.add(order);
	}

	public <T, R> Sort(SerializableFunction<T, R> column, Direction direction) {
		OrderBy order = new OrderBy();
		order.setColumn(ReflectionUtil.getFieldName(column));
		order.setDirection(direction);

		orderList.add(order);
	}

	public Sort add(String column, Direction direction) {
		OrderBy order = new OrderBy();
		order.setColumn(column);
		order.setDirection(direction);

		orderList.add(order);

		return this;
	}

	public <T, R> Sort add(SerializableFunction<T, R> column, Direction direction) {
		OrderBy order = new OrderBy();
		order.setColumn(ReflectionUtil.getFieldName(column));
		order.setDirection(direction);

		orderList.add(order);

		return this;
	}

	public Sort add(String orderByStr) {
		OrderBy order = new OrderBy();
		order.setOrderByStr(orderByStr);

		orderList.add(order);

		return this;
	}

	public String toString() {
		List<String> sqlList = new ArrayList<>();
		for (OrderBy order : orderList) {
			if (StrUtil.isEmpty(order.getOrderByStr())) {
				String sql = "`" + StrUtil.toUnderlineCase(order.getColumn()) + "`";

				if (order.getDirection() == Direction.ASC) {
					sql += " ASC";
				}
				if (order.getDirection() == Direction.DESC) {
					sql += " DESC";
				}

				sqlList.add(sql);
			} else {
				sqlList.add(order.getOrderByStr());
			}
		}
		if (sqlList.size() > 0) {
			return " ORDER BY " + StrUtil.join(",", sqlList);
		} else {
			return "";
		}

	}

	public List<OrderBy> getOrderList() {
		return orderList;
	}

	public void setOrderList(List<OrderBy> orderList) {
		this.orderList = orderList;
	}

}
