package com.yanzuoguang.cloud.excel;


import com.yanzuoguang.cloud.helper.HttpFileHelper;
import com.yanzuoguang.excel.*;
import com.yanzuoguang.util.YzgError;
import com.yanzuoguang.util.exception.ExceptionHelper;
import com.yanzuoguang.util.helper.FileHelper;
import com.yanzuoguang.util.helper.StringHelper;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;

/**
 * HTTP方式下载Excel文件
 *
 * @param <T> 行数据的类型
 * @author 颜佐光
 */
public class ExcelHttp<T> extends ExcelConsole<T> {

    /**
     * 导出成Excel
     *
     * @param exportData 导出信息
     */
    public ExcelHttp(ExportData exportData, ExcelStatus<T> excelStatus) {
        super(exportData, excelStatus);
    }

    /**
     * 导出成Excel
     *
     * @param config    导出信息
     * @param rowHandle 导出下载信息
     */
    public ExcelHttp(ExportData config, ExcelStatus<T> excelStatus, ExcelRow<T> rowHandle) {
        super(config, excelStatus, rowHandle);
    }

    /**
     * 下载文件
     *
     * @param response 输出流
     */
    public boolean down(HttpServletResponse response) throws IOException {
        return this.down(response, StringHelper.EMPTY);
    }

    /**
     * 下载文件
     *
     * @param response     输出流
     * @param downFileName 下载文件名
     */
    public boolean down(HttpServletResponse response, String downFileName) throws IOException {
        ExportData config = this.getConfig();
        if (StringHelper.isEmpty(downFileName)) {
            downFileName = config.getDownFileName();
        }
        if (StringHelper.isEmpty(downFileName)) {
            downFileName = config.getFileName();
        }
        // 正式文件
        String fileName = this.getFileName();
        File file = new File(fileName);

        if (file.exists()) {
            // 下载文件
            HttpFileHelper.localToDown(this.getFileName(), downFileName, response);
            return true;
        }

        return false;
    }

    /**
     * 导出数据
     *
     * @param req      请求对接
     * @param excelDao dao层实现接口
     */
    public static <T, M extends Object> ExcelHttp<M> export(ExportBase<T> req, ExcelDao<T, M> excelDao, ExcelStatus<M> excelStatus) {
        ExportData config = req.getConfig();
        if (config == null) {
            throw YzgError.getRuntimeException("024");
        }
        if (StringHelper.isEmpty(config.getServerPath())) {
            config.setServerPath("/home/cache/");
        }
        boolean isEmptyFile = StringHelper.isEmpty(config.getFileName());
        if (isEmptyFile) {
            config.setFileName(String.format("%s.xlsx", StringHelper.getNewID()));
        }
        if (StringHelper.isEmpty(config.getDownFileName())) {
            config.setDownFileName(String.format("%s-%s.xlsx", config.getTitle(), config.getSubTitle()));
        }

        FileHelper.checkFolder(config.getServerPath());
        FileHelper.checkFolder(config.getFileName());
        FileHelper.checkFolder(config.getDownFileName());

        ExcelHttp<M> excel = new ExcelHttp<>(config, excelStatus);
        // 普通模式生成文件并下载
        releaseExcel(req, excelDao, excel);

        return excel;
    }

    /**
     * 导出数据
     *
     * @param req      请求对接
     * @param response 输出结果
     * @param excelDao dao层实现接口
     */
    public static <T, M extends Object> ExcelHttp<M> export(ExportBase<T> req, HttpServletResponse response, ExcelDao<T, M> excelDao) {
        return export(req, response, excelDao, null);
    }

    /**
     * 导出数据
     *
     * @param req         请求对接
     * @param response    输出结果
     * @param excelDao    dao层实现接口
     * @param excelStatus excel状态实现
     */
    public static <T, M extends Object> ExcelHttp<M> export(ExportBase<T> req, HttpServletResponse response, ExcelDao<T, M> excelDao, ExcelStatus<M> excelStatus) {
        ExcelHttp<M> excel = export(req, excelDao, excelStatus);
        try {
            // 等待下载模式,下载文件
            excel.down(response);
        } catch (IOException e) {
            ExceptionHelper.PrintError(ExcelConsole.class, e);
            throw YzgError.getRuntimeException(e, "045", e.getMessage());
        } finally {
            // 删除生成的临时文件
            excel.remove();
        }
        return excel;
    }

    private static <T, M> void releaseExcel(ExportBase<T> req, ExcelDao<T, M> excelDao, ExcelHttp<M> excel) {
        excel.open();
        excelDao.export(excel, req.getCond());
        if (excelDao instanceof ExcelDaoFinish) {
            ((ExcelDaoFinish<T, M>) excelDao).finish(excel);
        }
        excel.save();
    }
}