package vn.azteam.tpf.service.util;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.persistence.Column;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.Tuple;

import org.springframework.data.domain.Pageable;

public final class NativeQueryUtil {
    private NativeQueryUtil() {
    }

    public static String getSortQuery(Pageable pageable, Class<?> cls) {
        String fields = pageable.getSort().stream().map(i -> {
            try {
                Field field = cls.getDeclaredField(i.getProperty());
                if (field.isAnnotationPresent(Column.class)) {
                    return field.getAnnotation(Column.class).name() + ' ' + i.getDirection().toString();
                }
                return null;
            } catch (Exception e) {
                return null;
            }
        })
        .filter(i -> i != null)
        .collect(Collectors.joining(", "));
        if (fields.length() == 0) {
            return "";
        }
        return "ORDER BY " + fields + "\n";
    }

    public static Query create(EntityManager em, String sql, Map<String, Object> params) {
        Query query = em.createNativeQuery(sql, Tuple.class);
        for (Map.Entry<String, Object> entry: params.entrySet()) {
            query.setParameter(entry.getKey(), entry.getValue());
        }
        return query;
    }


    public static int getTotalCount(EntityManager em, Query query, String sqlString) {
        Query queryTotal = em.createNativeQuery("SELECT count(*) \n" + sqlString);
        for(javax.persistence.Parameter<?> param : query.getParameters()) {
            String name = param.getName();
            queryTotal.setParameter(name, query.getParameterValue(name));
        }
        return ((Number) queryTotal.getSingleResult()).intValue();
    }


    public static List<Tuple> getPageResultList(Pageable pageable, Query query) {
        query.setFirstResult((int) pageable.getOffset())
        .setMaxResults(pageable.getPageSize());

        return query.getResultList();
    }
}