package com.ads.common.base;

import cn.hutool.core.util.StrUtil;
import com.ads.business.service.data.GetLoginOutData;
import com.ads.common.exception.BusinessException;
import com.ads.common.redis.RedisKeyConstant;
import com.ads.common.redis.RedisManager;
import com.ads.common.util.UtilConst;
import com.ads.common.util.UtilMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 作者 GXS
 * @date 创建时间 2018年3月21日 下午5:32:04
 * @description 控制层基类
 */
@Slf4j
public class BaseController {
    @Autowired
    private RedisManager redisManager;

    @InitBinder
    public void initBinder(ServletRequestDataBinder binder) {
        /**
         * 自动转换日期类型的字段格式
         */
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true));
    }

    /**
     * 获取用户信息
     * @author yuqiang
     * @date 2020/9/1 10:36 上午
     * @param request: 
     * @return com.ads.business.service.data.GetLoginOutData
     **/
    public GetLoginOutData getLoginUser(HttpServletRequest request) {
        GetLoginOutData userInfo = (GetLoginOutData) redisManager.get(request.getHeader(RedisKeyConstant.PREFIX + UtilConst.LOGIN_TOKEN));
        return userInfo;
    }


    /**
     * 导出Excel
     *
     * @param response
     * @param list
     * @param header
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    protected void exportExcel(HttpServletResponse response, List<?> list, String[] header, ExportExcelInterface export) throws Exception {
        Date dt = new Date();
        String fileName = new Long(dt.getTime()).toString();
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        OutputStream out = response.getOutputStream();
        try {
            export.exportExcel(header, list, out, "yyyy-MM-dd");
            out.flush();
        } catch (Exception e) {
            throw e;
        } finally {
            out.close();
        }
    }

    /**
     * 导入资源
     *
     * @param uploadExcel
     * @param sheetNo
     * @param t
     * @return
     * @throws IOException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws InstantiationException
     */
    @SuppressWarnings("resource")
    public <T> List<T> importExcel(MultipartFile uploadExcel, Class<T> t, Integer sheetNo, Integer firstRowNum) {
        List<T> list = new ArrayList<T>();
        try {
            Workbook workbook = null;
            String fileName = uploadExcel.getOriginalFilename();
            String fileEnd = fileName.substring(fileName.indexOf(".") + 1);
            Sheet sheet = null;
            // 兼容 2007及2003版本
            if ("xls".equals(fileEnd)) {
                workbook = new HSSFWorkbook(uploadExcel.getInputStream());
                sheet = (HSSFSheet) workbook.getSheetAt(sheetNo);
            } else {
                workbook = new XSSFWorkbook(uploadExcel.getInputStream());
                sheet = (XSSFSheet) workbook.getSheetAt(sheetNo);
            }
            for (int i = firstRowNum; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) {
                    continue;
                }
                T instance = t.newInstance();
                Field[] fields = instance.getClass().getDeclaredFields();
                int count = 0;
                int length = fields.length;
                for (int k = 0; k < length; k++) {
                    Method setMethod = instance.getClass().getMethod("set" + StringUtils.capitalize(fields[k].getName()), String.class);
                    if (k == length - 1) {
                        String index = i + 1 + "";
                        setMethod.invoke(instance, index);
                        continue;
                    }
                    Cell cell = row.getCell(k);
                    if (cell == null) {
                        setMethod.invoke(instance, "");
                        count++;
                    } else {
                        cell.setCellType(CellType.STRING);
                        if (StrUtil.isBlank(cell.getStringCellValue())) {
                            count++;
                        }
                        setMethod.invoke(instance, cell.getStringCellValue());
                    }
                }
                if (count != length - 1) {
                    list.add(instance);
                }
            }
        } catch (Exception e) {
            log.error("导入失败:", e);
            throw new BusinessException(UtilMessage.IMPORT_MESSAGE_ERROR);
        }

        return list;
    }


}
