package cn.com.countrygarden.bi.main.util.wcx;

import cn.com.countrygarden.bi.main.annotation.DescribeAnno;
import cn.com.countrygarden.bi.main.dao.twerp.hm.ManagerMapForErpMapper;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class ExcepExportUtil<T> {
    @Autowired
    private ManagerMapForErpMapper managerMapForErpMapper;
    private static ExcepExportUtil excepExportUtil;
    @PostConstruct
    public void init() {
        excepExportUtil = this;
        excepExportUtil.managerMapForErpMapper = this.managerMapForErpMapper;
    }
    /**
     * fileName 导出文件名含后缀
     * fileLocalUrl 服务器存放模板文件
     * sheetName sheet名
     * list 导出数据
     * <T>  导出实体内
     * num 从第N行开始写入
     * */
    public void export(String fileName, String fileLocalUrl, String sheetName,HttpServletResponse response, List<T> list,int num) throws IOException {
        InputStream io= new ClassPathResource(fileLocalUrl).getInputStream();
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
        XSSFWorkbook xSSFWorkbook=new XSSFWorkbook(io);
        Sheet sheet = xSSFWorkbook.getSheet(sheetName == null ?"Sheet1":sheetName);
        try{
            int i=num;
            for(int j=0;j<list.size();j++){
                T t = list.get(j);
                Row row = sheet.createRow(i);
                int i1 = writeExcel(row, t, sheet);
                if(i1 !=0){
                    i=i+i1-1;
                }
                i++;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            xSSFWorkbook.write(response.getOutputStream());
            response.getOutputStream();
        }
    }

    /**
     * 通过反射获取泛型类，获取属性注解，依次填入excel中
     * 每一行处理后判断是否有合并行，如果没有则返回0
     * */
    public int writeExcel(Row row,T t,Sheet sheet){
        Map<String,Map<String,String>> resultMap=new HashMap<String,Map<String,String>>();
        List<String> list = readAnno(t,resultMap);
        for(int i=0;i<list.size();i++){
            String name = list.get(i);
            if(name ==null || name ==""){
                continue;
            }
            String value2 = getValue2(t, name,resultMap);
            //TODO 如果返回封装类型及list可单独处理
//            if(value2 instanceof List){
//            //TODO
//            };
//            if(value2 instanceof String){
//                i=i;
//            }
//            if(value2 instanceof Integer){
//                i=i;
//            }
//            if(value2 instanceof Float){
//                i=i;
//            }
//            if(value2 instanceof Double){
//                i=i;
//            }
//            if(value2 instanceof Long){
//                i=i;
//            }
//            if(value2 instanceof BigDecimal){
//                i=i;
//            }
            Cell cell= row.createCell(i);;
            cell.setCellValue("null".equals(value2)?"":value2);
        }
        //如果返回List，需判断list的大小，然后合并其他数据行并返回最大的行号
        return 0;
    }
    /**
     * 获取反射的值*/
    public String getValue2(T t,String name,Map<String,Map<String,String>> map) {
        try{
            String getMethodName = "get" + name.substring(0, 1).toUpperCase()
                    + name.substring(1);
            Class tCls = t.getClass();
            Method getMethod = tCls.getMethod(getMethodName, new Class[] {});
            Object value = getMethod.invoke(t, new Object[] {});
            Map<String, String> stringStringMap = map.get(name);
            if(stringStringMap != null){
                //存在转换值
                String s = stringStringMap.get(value+"");
                if(s !=null && s != ""){
                    return s;
                }
            }
            if("organCode".equals(name)){
                if(value !=null && value !=""){
                    String s = excepExportUtil.managerMapForErpMapper.selectOrgNameByCode(value + "");
                    return s;
                }
            }
            if("commId".equals(name)){
                if(value !=null && value !=""){
                    String getMethodName2 = "getOrganCode";
                    Class tCls2 = t.getClass();
                    Method getMethod2 = tCls2.getMethod(getMethodName2, new Class[] {});
                    Object value2 = getMethod2.invoke(t, new Object[] {});
                    String commName=excepExportUtil.managerMapForErpMapper.queryCommNameByOrganCodeAndCommId(value2.toString(),value.toString());
                    return commName;
                }
            }
            return value+"";
        }catch(Exception e){
            e.printStackTrace();
            return "";
        }
    }
    /**
     * 读取泛型类上的注解
     * */
    public List<String>  readAnno(T t,Map<String,Map<String,String>> resultMap){
        List<String> list=new ArrayList<String>();
        Class tCls = t.getClass();
        Field[] fields = tCls.getDeclaredFields();
        for (Field f : fields) {
            Annotation[] annotations = f.getAnnotations();
            for(Annotation annotation:annotations){
                if(annotation instanceof Excel){
                    String s = ((Excel) annotation).orderNum();
                    int i = Integer.parseInt(s);
                    if(i>list.size()+1){
                        addListNull(list,i,f.getName());
                    }else{
                        //已存在下标则set、不存在则add
                        changeListValue(list,i,f.getName());
                    }
                }
                if(annotation instanceof DescribeAnno){
                    HashMap<String,String> hashMap=new HashMap();
                    String[] value = ((DescribeAnno) annotation).value();
                    String[] name = ((DescribeAnno) annotation).name();
                    for(int i=0;i<value.length;i++){
                        hashMap.put(value[i],name[i]);
                    }
                    resultMap.put(f.getName(),hashMap);
                }
            }
        }
        return list;
        }
        /**
         * list添加空
         * */
        public void addListNull( List<String> list,int i,String s){
            int size = list.size();
            for(int j=size;j<i-1;j++){
                list.add(j,"");
            }
            list.add(i-1,s);
        }
    /**
     * list判断是否有值
     * */
    public void changeListValue(List<String> list,int i,String s){
        int size = list.size();
        if(i == size+1){
            list.add(i-1,s);
        }else{
            list.set(i-1,s);
        }
    }
}
