package com.ywt.mg.services.enterprise;

import com.ywt.mg.configs.DomainConfigurer;
import com.ywt.mg.core.SqlHelper;
import com.ywt.mg.core.utils.Checker;
import com.ywt.mg.core.utils.FileUtil;
import com.ywt.mg.core.utils.GeneratePdf;
import com.ywt.mg.core.utils.ZipFileUtil;
import com.ywt.mg.core.utils.serializers.JsonSerializer;
import com.ywt.mg.domain.entities.*;
import com.ywt.mg.domain.models.ConstantDef;
import com.ywt.mg.params.enterprise.marketting.BatchDownloadFilesRequest;
import com.ywt.mg.services.AuthService;
import com.ywt.mg.web.DataResponse;
import com.ywt.mg.web.common.FileSrv;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.security.SecureRandom;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class ApplyProjectService {

    private static final Logger logger = LoggerFactory.getLogger(ApplyProjectService.class);

    @Autowired
    private SqlHelper sqlHelper;
    @Autowired
    private AuthService authservice;
    @Autowired
    private MarketingApplyRepository marketingApplyRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private MarketingImageRepository marketingImageRepository;
    @Autowired
    private MarketingJobTypeUserRepository marketingJobTypeUserRepository;
    @Autowired
    private DomainConfigurer domainConfigurer;
    @Autowired
    private MarketingProjectRepository marketingProjectRepository;
    @Autowired
    private FileSrv fileSrv;

    public static final String APPLY_PROJECT_FILE_PATH = "./apply_project_file/files/";
    public static final String APPLY_PROJECT_ROOT_PATH = "./apply_project_file/";


    /**
     * 批量下载文件：
     * 1、先根据从前端选择的条件去数据库查找对应的记录
     * 2、遍历记录去下载对应的文件到服务器；
     * 3、将下载的文件打包；
     * 4、将打包的文件传给客户端
     * 5、删掉之前所有的文件；
     *
     * @param request
     * @return
     */
    public void batchDownloadFiles(BatchDownloadFilesRequest request, HttpServletResponse response) {
        int number = (int) (Math.random() * 1000);
        String filePrefix = APPLY_PROJECT_FILE_PATH + number + "/";
        String rootPrefix = APPLY_PROJECT_ROOT_PATH + number + "/";
        try {
            // 1、先根据从前端选择的条件去数据库查找对应的记录
            Map<String, String> item = new HashMap<>();
//            item.put("测试文档测试文档测试文档测试文档.doc", "https://ywt-files.oss-cn-shenzhen.aliyuncs.com//up/marketting_project/public/9-a30e19ed1c8d4b28ba83eb7a88a4f985.doc");
//            item.put("下载.jpg", "https://ywt-files.oss-cn-shenzhen.aliyuncs.com//up/marketting_project/public/9-bb077b3512074ddaae0a12d797f20d02.jpg");
//            item.put("测试文档.pdf", "https://ywt-files.oss-cn-shenzhen.aliyuncs.com//up/marketting_project/public/9-1b9a0a24f2be4cef882a22d1a5750ae5.pdf");

            List<MarketingImage> marketingImageList = getMarketingImageList(request);
            if (Checker.isNone(marketingImageList)) {
                return;
            }
            for (int i = 0, j = marketingImageList.size(); i < j; i++) {
                MarketingImage image = marketingImageList.get(i);
                item.put(i + "_" + image.getName(), image.getImageUrl());
            }

            // 2、遍历记录去下载对应的文件到服务器；
            List<String> fileUrl = new ArrayList<>();
            for (Map.Entry<String, String> entry : item.entrySet()) {
                logger.info(entry.getKey() + "--->" + entry.getValue());
                if (Checker.isNone(entry.getKey()) || Checker.isNone(entry.getValue())) {
                    continue;
                }
                String urlLink = entry.getValue();
                String pathName = filePrefix + entry.getKey();
                // 下载单个文件
                downloadSingleFile(urlLink, pathName);
                fileUrl.add(pathName);
            }
            // 3、将下载的文件打包
            String zipFileName = "资料";
            if (!Checker.isNone(request.getCreateTimeStart()) && !Checker.isNone(request.getCreateTimeEnd())) {
                String fileNameDate = request.getCreateTimeStart().replace("-", "") + "~" + request.getCreateTimeEnd().replace("-", "");
                zipFileName += fileNameDate;
            }
            zipFileName += ".zip";
            FileUtil.createFoldersIfNotExit(rootPrefix + zipFileName);
            ZipFileUtil.stringFileUrlToZip(rootPrefix + zipFileName, fileUrl);

            // 4、将打包的文件传给客户端
            downFile(response, rootPrefix, zipFileName);
        } catch (Exception e) {
            logger.error("ApplyProjectService#batchDownloadFiles(request:{}){}", JsonSerializer.toJson(request), e.getMessage(), e);
        } finally {
            // 5、删掉之前所有的文件；
            FileUtil.deleteFolders(filePrefix);
            FileUtil.deleteFolders(rootPrefix);
        }
    }

    private List<MarketingImage> getMarketingImageList(BatchDownloadFilesRequest request) {
        List<Object> paramList = new ArrayList<>();
        String whereSql = " ( 1=1 )";
        whereSql += " and deleted = 0 and (type = 7 or type = 8)";
        int applyId = Checker.getIntegerValue(request.getId());
        if (applyId > 0) {
            whereSql += " and (apply_id = ?)";
            paramList.add(applyId);
        }

        String formatDate = "yyyy-MM-dd";
        SimpleDateFormat format = new SimpleDateFormat(formatDate);
        try {
            String createTime = request.getCreateTimeStart();
            if (!Checker.isNull(createTime)) {
                whereSql += " and (create_time >= ?)";
                Date date = format.parse(createTime);
                paramList.add(date);
            }
            String createEndTime = request.getCreateTimeEnd();
            if (!Checker.isNull(createEndTime)) {
                whereSql += " and ( create_time < ? )";
                Date date = format.parse(createEndTime);

                //把日期往后增加一天.整数往后推,负数往前移动
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(date);
                calendar.add(Calendar.DATE, 1);
                //这个时间就是日期往后推一天的结果
                date = calendar.getTime();
                paramList.add(date);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return sqlHelper.getList("*", whereSql, "create_time desc", MarketingImage.class, paramList.toArray());
    }

    /**
     * 下载单个文件到服务器
     *
     * @param urlLink  oss的路径地址
     * @param pathName 本地文件（包含文件所在路径以及文件名称）
     */
    private static void downloadSingleFile(String urlLink, String pathName) {
        try {
            FileUtil.createFoldersIfNotExit(pathName);
            URL url = new URL(urlLink);
            //打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream。
            InputStream inputStream = url.openStream();
            File file = new File(pathName);
            OutputStream outputStream = new FileOutputStream(file);
            int byteCount = 0;
            //1M逐个读取
            byte[] bytes = new byte[1024 * 1024];
            while ((byteCount = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, byteCount);
            }
            inputStream.close();
            outputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将本地zip返回给前端
     *
     * @param response
     * @param FilePath
     * @param str
     */
    private void downFile(HttpServletResponse response, String FilePath, String str) {
        Map m = new HashMap();
        try {
            String path = FilePath + str;
            File file = new File(path);
            if (file.exists()) {
                InputStream ins = new FileInputStream(path);
                // 放到缓冲流里面
                BufferedInputStream bins = new BufferedInputStream(ins);
                // 获取文件输出IO流
                OutputStream outs = response.getOutputStream();
                BufferedOutputStream bouts = new BufferedOutputStream(outs);
                response.addHeader("content-disposition", "attachment;filename=" + new String(str.getBytes(), "iso-8859-1"));
                int bytesRead = 0;
                //1M逐个读取
                byte[] bytes = new byte[1024 * 1024];
                // 开始向网络传输文件流
                while ((bytesRead = bins.read(bytes)) != -1) {
                    bouts.write(bytes, 0, bytesRead);
                }
                // 这里一定要调用flush()方法
                bouts.flush();
                ins.close();
                bins.close();
                outs.close();
                bouts.close();
            }
        } catch (IOException e) {
            m.put("code", "-1");
            m.put("text", "附件下载出错：" + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 创建PDF文件：
     * <p>
     * 1、先根据从前端选择的条件去数据库查找对应的记录
     * 2、遍历记录去下载对应的文件到服务器；
     * 3、生成pdf
     * 4、上传到oss
     * 5、删掉之前所有的文件；
     *
     * @param request
     */
    public void createPDF(BatchDownloadFilesRequest request) {
        int number = (int) (Math.random() * 1000);
        String filePrefix = APPLY_PROJECT_FILE_PATH + number + "/";
        String rootPrefix = APPLY_PROJECT_ROOT_PATH + number + "/";
        try {
            // 1、先根据从前端选择的条件去数据库查找对应的记录
            Map<String, String> item = new HashMap<>();
            item.put("1", "c23401c928d841e79be95479d8e68144jpeg");
            item.put("2", "05c8799a202e45ebbedd3e81c790fc87jpeg");
            item.put("3", "266d03218ca94683a022c6502f59357cjpeg");

            item.put("4", "c6ec2e8f87194190a75012c52b7b29ebjpeg");
            item.put("5", "0f7e4fccaebf4c5581d5742c48b5209ejpeg");
            item.put("6", "ec48ac7b51994507a31a4e8a90aa56a6jpeg");

            item.put("7", "dccf09a43dfb449f91ad26fce588fcc6jpeg");
            item.put("8", "89d6df3dd1cd4c29937e1f46899ac6e4jpeg");
            item.put("9", "ff31f865218240c5a37729352296ea25jpeg");

            // 2、遍历记录去下载对应的文件到服务器；
            List<String> fileUrl = new ArrayList<>();
            for (Map.Entry<String, String> entry : item.entrySet()) {
                logger.info(entry.getKey() + "--->" + entry.getValue());
                if (Checker.isNone(entry.getKey()) || Checker.isNone(entry.getValue())) {
                    continue;
                }
                String urlLink = "up/marketting_project" + "/" + entry.getValue();
                String pathName = filePrefix + entry.getKey() + ".jpg";
                // 下载单个文件
                downloadSingleFileFromGrpc(urlLink, pathName);
                fileUrl.add(pathName);
            }
            // 3、生成pdf
            String word = "12345678901234567890312345678901234567890123456789012345678901啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦！！！！234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
            String fileName = "资料.pdf";
            String pdfPath = rootPrefix + fileName;
            createPDF(word, fileUrl, pdfPath);

            // 4、上传到OSS
            DataResponse dataResponse = fileSrv.localFileUploadToOss(rootPrefix, fileName, ConstantDef.MARKER_PROJECT_PATH_PUBLIC);
            logger.info("ApplyProjectService#createPDF ossUrl:-->" + dataResponse.getData());
        } catch (Exception e) {
            logger.error("ApplyProjectService#batchDownloadFiles(request:{}){}", JsonSerializer.toJson(request), e.getMessage(), e);
        } finally {
            // 5、删掉之前所有的文件；
            FileUtil.deleteFolders(rootPrefix);
            FileUtil.deleteFolders(filePrefix);
        }
    }

    private void createPDF(String word, List<String> fileUrl, String pdfPath) {
        FileUtil.createFoldersIfNotExit(pdfPath);
        GeneratePdf gp = new GeneratePdf();
        gp.Pdf(word, fileUrl, pdfPath);
    }

    /**
     * 下载单个文件到服务器
     *
     * @param urlLink  oss的路径地址
     * @param pathName 本地文件（包含文件所在路径以及文件名称）
     */
    private void downloadSingleFileFromGrpc(String urlLink, String pathName) {
        BufferedOutputStream bufferedOutput = null;
        FileOutputStream outputStream = null;
        File file = null;
        try {
            FileUtil.createFoldersIfNotExit(pathName);
            byte[] fileBytes = fileSrv.readFile(urlLink);
            //打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream。
            file = new File(pathName);
            outputStream = new FileOutputStream(file);
            bufferedOutput = new BufferedOutputStream(outputStream);
            bufferedOutput.write(fileBytes);
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bufferedOutput != null) {
                try {
                    bufferedOutput.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
}
