package org.ccpit.base.utils.page;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.ccpit.base.controller.Convert;
import org.ccpit.base.controller.Page;
import org.ccpit.base.controller.PageBo;
import org.ccpit.base.utils.CommonUtils;
import org.ccpit.base.utils.MethodInterface;


/**
 * @author liyang
 *
 * 	PageUtil2.0版本
 *  本类为了加快开发速度
 */

public  class PageUtil {
	
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd ");
	/**
	 * paramToSql 该方法可以根据注解自动生成后台查询sql(实现动态查询sql)
	 *  
	 * */
	@SuppressWarnings("unchecked")
	public static <T>String paramToSql(HttpServletRequest request, T t) {
		//确定这个参数是否与实体类有关的标识
		//最终返回sql 
		StringBuffer sql = new StringBuffer("from "+ t.getClass().getSimpleName() + " where 1=1  ");
		//利用反射得到实体类
		try {
			Class<?> clazz = Class.forName(t.getClass().getName());
			Field fields []=clazz.getDeclaredFields(); 
			List<Field> fieldList = Arrays.asList(fields);
			//获取全部查询条件
			Enumeration<String> enu =  request.getParameterNames(); 
			while(enu.hasMoreElements()){  
				//获得参数名字
				String paraName=enu.nextElement();  
				//顾虑掉一些无关参数
				long i = fieldList.stream().filter(f->f.getName().equals(paraName)).count();
				//按得到的条件进行参数拼接
				if(i<=0){
					continue;
				}
				Field field  = clazz.getDeclaredField(paraName);
				Column column= field.getAnnotation(Column.class); 
				System.out.println(column.method());
				if("like".equals(column.method().toString())){
					sql.append(" and "+paraName+" like '%"+request.getParameter(paraName)+"%'");
				}else if("equal".equals(column.method().toString())){
					sql.append(" and "+paraName+" = '"+request.getParameter(paraName)+"'");
				}else if ("gt".equals(column.method().toString())){
					sql.append(" and "+paraName+" > '"+request.getParameter(paraName)+"'");
				}else if ("lt".equals(column.method().toString())){
					sql.append(" and "+paraName+" < '"+request.getParameter(paraName)+"'");
				}else if ("ge".equals(column.method().toString())){
					sql.append(" and "+paraName+" >= '"+request.getParameter(paraName)+"'");
				}else if ("le".equals(column.method().toString())){
					sql.append(" and "+paraName+" <= '"+request.getParameter(paraName)+"'");
				}else if ("in".equals(column.method().toString())){
					sql.append(" and "+paraName+" in '"+request.getParameter(paraName)+"'");
				}
			}
			//获取排序字段
			 sql.append(" order by ");
			 Ordering odering = clazz.getAnnotation(Ordering.class);
			 List<String> orders = Arrays.asList(odering.ordering().split(","));
			 List<String> orderType = Arrays.asList(odering.type().split(","));
/*			 for(int i=0,size=orders.size();i<size;i++){
				 if(i==0){
					 sql.append(orders.get(i)+" "+orderType.get(i));
				 }else{
					 sql.append(","+orders.get(i)+" "+orderType.get(i)); 
				 }
			 }*/
			 for(int i=0,size=orders.size();i<size;i++){
				 sql.append(i==0?orders.get(i)+" "+orderType.get(i): ","+orders.get(i)+" "+orderType.get(i));
				 
			 }
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    		return sql.toString();
	}
	
	//将一个对象完全转化为map
	/**
	  * convertToMap :(将T实体类转化为map). <br/> 
	  * @author ly: 
	  * @date 创建时间:2016-4-18 上午10:53:04 
	  * @version 1.0 
	  * @parameter investInfo
	  * @since  
	  * @return Map<String,Object>
	  *
	 */
	public static <T>Map<String,Object> convertToMap(T t){
 		Class<?> clazz  = null;
        Map<String,Object> map = new HashMap<String, Object>();
        if (t==null){
        	return map;
        }
    try {
         clazz = Class.forName(t.getClass().getName());
         //获取全部属性
        Field[] fields = clazz.getDeclaredFields();
        for (int i=0,size =fields.length;i<size;i++){
        	//获取field
        	Field field = fields[i];
        	//获取get方法  
        	String method = "get"+toUpperCaseFirstOne(field.getName());
        	Method [] methods = clazz.getDeclaredMethods();
        	long num = Arrays.asList(methods).stream().filter(md->md.getName().equals("get"+toUpperCaseFirstOne(field.getName()))).count();
        	if(num==0){
        		method= "is"+toUpperCaseFirstOne(field.getName());
        	}
        	//获取value
			Object value = clazz.getDeclaredMethod(method).invoke(t);
        	//如果返回值为Date
				if(clazz.getDeclaredMethod(method).getReturnType().getSimpleName().equals("Date")&&value!=null){
					Timestamp timer = (Timestamp) value;
					map.put(field.getName(), sdf.format(new java.util.Date((timer.getTime()))));
				}else{
					map.put(field.getName(), value);
				}
        	}   
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
		  } 
        	return map;
    }
	
	 public  static <T> PageBo<T> convert(Page<T> page, MethodInterface method){
	    	if(null == page){
	    		return null;
	    	}
	        return new PageBo<T>(page, new Convert<T>() {
	            @Override
	            public Map<String, Object> convert(T obj) {
	                return method.replaceValue((convertToMap(obj)));
	            }
	        });
	   	}
	 
		//判断属性值是否为空若为空就跳过非空则赋值param t1 为前台提交 t2为已经存在的数据
		public static<T> T setterValues(T t1,T t2){
			try {
		        Class<?> clazz = Class.forName(t1.getClass().getName());
		        Class<?> clazz2 = Class.forName(t2.getClass().getName());
		        //获取全部属性
		        Field[] fields = clazz.getDeclaredFields();
		        for (int i=0,size =fields.length;i<size;i++){
		        	//获取field
		        	Field field = fields[i];
		        	if(field.getName().equals("deleted")||field.getName().equals("id")||field.getName().equals("serialVersionUID")){
		        		continue;
		        	}
		        	//获取get方法  
		        	String method1 = "get"+toUpperCaseFirstOne(field.getName());
		        	String method2 = "set"+toUpperCaseFirstOne(field.getName());
		        	//获取value
		        	Object value = clazz.getDeclaredMethod(method1).invoke(t1);
		        	Class<?> returnType = clazz.getDeclaredMethod(method1).getReturnType();
		        	//如果返回值为Date
		        	//如果为int
		        	if (returnType.equals(int.class)) {
		        		Method method = clazz2.getDeclaredMethod(method2, returnType);
		        		value = CommonUtils.isNull(value) ? 0 : value;
	        			method.invoke(t2, value);
		        	}
		        	if (returnType.equals(long.class)) {
		        		Method method = clazz2.getDeclaredMethod(method2, returnType);
		        		value = CommonUtils.isNull(value) ? 0 : value;
	        			method.invoke(t2, value);
		        	}
		        	if (returnType.equals(float.class)) {
		        		Method method = clazz2.getDeclaredMethod(method2, returnType);
		        		value = CommonUtils.isNull(value) ? 0.f : value;
	        			method.invoke(t2, value);
		        	}
		        	if (returnType.equals(double.class)) {
		        		Method method = clazz2.getDeclaredMethod(method2, returnType);
		        		value = CommonUtils.isNull(value) ? 0.0 : value;
	        			method.invoke(t2, value);
		        	}
		        	if(value != null) {
		        			Method method = clazz2.getDeclaredMethod(method2, returnType);
		        			method.invoke(t2, value);		        			
		        	}
		        }
			} catch (Exception e) {
				e.printStackTrace();
			} 
			return t2;
		}
		
	
//--------------------------------------------------------------------------------------------------------------------------------	
		
		
		
	//首字母转小写
    public static String toLowerCaseFirstOne(String s)
    {
        if(Character.isLowerCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
    }
    //首字母转大写
    public static String toUpperCaseFirstOne(String s)
    {
        if(Character.isUpperCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
    }
	
	
}