package com.chinaweal.aiccs.aiccs.abnormal.service.impl;

import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chinaweal.aiccs.aiccs.abnormal.dto.PYRequestDTO;
import com.chinaweal.aiccs.aiccs.abnormal.entity.TSAttachment;
import com.chinaweal.aiccs.aiccs.abnormal.entity.Toincludeabn;
import com.chinaweal.aiccs.aiccs.abnormal.mapper.TSAttachmentMapper;
import com.chinaweal.aiccs.aiccs.abnormal.service.TSAttachmentService;
import com.chinaweal.aiccs.aiccs.abnormal.service.TSBizSpeListService;
import com.chinaweal.aiccs.aiccs.abnormal.service.ToincludeabnService;
import com.chinaweal.aiccs.aiccs.abnormal.utils.Base64Utils;
import com.chinaweal.aiccs.aiccs.revoke.Vo.DisableListVo;
import com.chinaweal.aiccs.aiccs.revoke.entity.dto.AttachmentWritDto;
import com.chinaweal.aiccs.common.constant.Constant;
import com.chinaweal.aiccs.common.util.FtpUtil;
import com.chinaweal.aiccs.common.util.StringUtils;
import com.chinaweal.aiccs.common.util.filestorage.FileStorageService;
import com.chinaweal.aiccs.config.CommonConfig;
import com.chinaweal.youfool.framework.springboot.exception.custom.BusinessException;
import com.chinaweal.youfool.framework.springboot.mybatis.plus.BaseServiceImpl;
import com.google.common.collect.Lists;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 监管附件上传信息表 服务实现类
 * </p>
 *
 * @author <a href="https://blog.lroyia.top">lroyia</a>
 * @since 2021-01-19
 */
@Service
public class TSAttachmentServiceImpl extends BaseServiceImpl<TSAttachmentMapper, TSAttachment> implements TSAttachmentService {

    @Value("${forest.variables.gzAicodsDownload}")
    private String downLoadPath;

    @Lazy
    @Resource
    private ToincludeabnService toincludeabnService;

    @Lazy
    @Autowired
    private TSBizSpeListService bizSpeListService;
    @Resource
    private FileStorageService fileStorageService;
    @Resource
    private FtpUtil ftpUtil;

    @Override
    public List<TSAttachment> selectwritByPage(TSAttachment tsWritModel) {
        return baseMapper.selectttachment(tsWritModel);
    }

    @Override
    public List<TSAttachment> getByPripidAndBizseq(String pripid, String bizseq) {
        LambdaQueryWrapper<TSAttachment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TSAttachment::getBizseq, bizseq)
                .eq(TSAttachment::getPripid, pripid);
        return list(wrapper);
    }

    @Override
    public void exportExcel(HttpServletRequest request, HttpServletResponse response, String fileName, List<DisableListVo> list) {
        ExcelWriter writer = null;
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            //添加响应头信息
            response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("application/msexcel;charset=UTF-8");//设置类型
            response.setHeader("Pragma", "No-cache");//设置头
            response.setHeader("Cache-Control", "no-cache");//设置头
            response.setDateHeader("Expires", 0);//设置日期头
            //实例化 ExcelWriter，传入输出流，excel格式，表头true
            writer = new ExcelWriter(outputStream, ExcelTypeEnum.XLSX, true);

            //使用Lists.partition 将list集合按指定长度进行切分，避免导出数据量大于excel的上限
            List<List<DisableListVo>> partition = Lists.partition(list, 10000);
            for (int i = 1; i <= partition.size(); i++) {
                com.alibaba.excel.metadata.Sheet sheet = new com.alibaba.excel.metadata.Sheet(i, 0, DisableListVo.class);
                sheet.setSheetName("清单" + i);
                //输出
                writer.write(partition.get(i - 1), sheet);
            }
            writer.finish();
            outputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("导出excel出错");
        } finally {
            try {
                response.getOutputStream().close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void exportExcel2(HttpServletRequest request, HttpServletResponse response, String fileName, List<?> list, Class<? extends BaseRowModel> clazz) {
        ExcelWriter writer = null;
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            //添加响应头信息
            response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("application/msexcel;charset=UTF-8");//设置类型
            response.setHeader("Pragma", "No-cache");//设置头
            response.setHeader("Cache-Control", "no-cache");//设置头
            response.setDateHeader("Expires", 0);//设置日期头
            //实例化 ExcelWriter，传入输出流，excel格式，表头true
            writer = new ExcelWriter(outputStream, ExcelTypeEnum.XLSX, true);

            //使用Lists.partition 将list集合按指定长度进行切分，避免导出数据量大于excel的上限
            List<? extends List<?>> partition = Lists.partition(list, 10000);
            for (int i = 1; i <= partition.size(); i++) {
                com.alibaba.excel.metadata.Sheet sheet = new com.alibaba.excel.metadata.Sheet(i, 0, clazz);
                sheet.setSheetName("清单" + i);
                //输出
                writer.write(partition.get(i - 1), sheet);
            }
            writer.finish();
            outputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("导出excel出错");
        } finally {
            try {
                response.getOutputStream().close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public List<TSAttachment> getAbnIncFileList(String bizseq) {
        LambdaQueryWrapper<TSAttachment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TSAttachment::getBizseq, bizseq)
                .ne(TSAttachment::getAttachtype, "0");// "0"为名单导入附件
        return list(wrapper);
    }

    @Override
    public List<TSAttachment> getIllegalIncFileList(String bizseq) {
        LambdaQueryWrapper<TSAttachment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TSAttachment::getBizseq, bizseq);
        return list(wrapper);
    }

    @Override
    public boolean saveClueFile(String files, String bizseq) {

        Map<String, String> fileMap = JSONObject.parseObject(files, Map.class);
        for (Map.Entry<String, String> entry : fileMap.entrySet()) {
            String fileName = entry.getKey();
            String fileValue = entry.getValue();
            String ext = StringUtils.isNotBlank(fileName) && fileName.lastIndexOf(Constant.DOT) > -1 ? fileName.substring(fileName.lastIndexOf(Constant.DOT)) : StringUtils.EMPTY;

            TSAttachment tsAttachmentModel = new TSAttachment();
            String id = UUID.randomUUID().toString();
            tsAttachmentModel.setAttachmentid(id);
            tsAttachmentModel.setBizseq(bizseq);
            tsAttachmentModel.setPripid(StringUtils.EMPTY);
            tsAttachmentModel.setFileext(ext);
            fileName = bizseq + fileName;
            tsAttachmentModel.setFilename(fileName);
            tsAttachmentModel.setTemppath(fileValue);
            tsAttachmentModel.setFileurl(fileValue);
            tsAttachmentModel.setLauptime(LocalDateTime.now());
            tsAttachmentModel.setAttachtype("1");
            tsAttachmentModel.setUploaddate(LocalDate.now());
//            tsAttachmentModel.setCreatetype("2"); // 直接读取双随机系统的附件
//            save(tsAttachmentModel);
            // 下载
            // 转换特殊数据
            String realPath = CommonConfig.getUploadPathByDate();
            String uploadPath = realPath + File.separator + "abnormal";
            String fileUrl = fileValue;
            if (!fileUrl.startsWith("date")) {
                String fileLast = fileUrl.substring(22);
                String date = fileUrl.substring(11, 21);
                fileUrl = "date=" + date + "&fileLast=" + fileLast;
            }

            String uir = downLoadPath + "?" + fileUrl;
            CloseableHttpClient httpclient = HttpClients.createDefault();
            HttpGet httpget = new HttpGet(uir);
            HttpResponse response = null;
            InputStream in = null;
            try {
                response = httpclient.execute(httpget);
                HttpEntity entity = response.getEntity();
                in = entity.getContent();
                // 上传ftp
                Boolean rs = fileStorageService.writeFromStream(uploadPath, fileName, in);
                if (rs) {
                    String tempPath = uploadPath + File.separator + fileName;
                    // 保留fileuril字段，更新temppath字段
                    tsAttachmentModel.setTemppath(tempPath);
                    tsAttachmentModel.setCreatetype("0");
                }
                save(tsAttachmentModel);
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

//        if(CollectionUtils.isNotEmpty(files)) {
//            for (MultipartFile file : files) {
//
//            String realPath = CommonConfig.getUploadPath();
//            realPath += File.separator + "aicodsGZ" + File.separator + bizseq;
//            String fileName = file.getOriginalFilename();
//            String ext = StringUtils.isNotBlank(fileName) && fileName.lastIndexOf(Constant.DOT) > -1 ? fileName.substring(fileName.lastIndexOf(Constant.DOT)) : StringUtils.EMPTY;
//            String contentType = file.getContentType();//文件的类型（MIME）、内容类型
////        String tempPath = CommonConfig.getUploadPath() + File.separator + "aicodsGZ" + File.separator + bizseq + File.separator + fileName;
//            String tempPath = "aicodsGZ" + File.separator + bizseq + File.separator + fileName;
//
//            try {
//                fileStorageService.writeFromStream(realPath, fileName, file.getInputStream());
//            } catch (Exception e) {
//                e.printStackTrace();
//                throw new BusinessException(e.getMessage());
//            }
//            TSAttachment tsAttachmentModel = new TSAttachment();
//            tsAttachmentModel.setBizseq(bizseq);
//            tsAttachmentModel.setPripid(StringUtils.EMPTY);
//            tsAttachmentModel.setFileext(ext);
//            tsAttachmentModel.setFilename(fileName);
//            tsAttachmentModel.setTemppath(tempPath);
//            tsAttachmentModel.setAttachtype("1");
//            tsAttachmentModel.setUploaddate(LocalDate.now());
//            save = save(tsAttachmentModel);
//            }
//        }
        return true;
    }

    @Override
    public boolean saveBatchWithList(List<TSAttachment> list) {
        return baseMapper.saveBatchWithList(list);
    }

    @Override
    public IPage<AttachmentWritDto> selectWritsList(IPage<AttachmentWritDto> page, AttachmentWritDto attachmentWritDto) {
        return baseMapper.selectWritsList(page, attachmentWritDto);
    }

    @Override
    public List<TSAttachment> queryFileByHistory(String SAPPROVECODE) {
        return baseMapper.queryFileByHistory(SAPPROVECODE);
    }

    @Override
    public TSAttachment queryHistoryFileById(String sevidencecode) {
        return baseMapper.queryHistoryFileById(sevidencecode);
    }

    @Override
    public boolean saveYMLCClueFile(List<PYRequestDTO.Attachment> files, Toincludeabn toincludeabn) {
        for (PYRequestDTO.Attachment file : files) {
            String fileName = file.getOriginalFilename();
            TSAttachment tsAttachmentModel = new TSAttachment();
            String id = UUID.randomUUID().toString();
            tsAttachmentModel.setAttachmentid(id);
            tsAttachmentModel.setBizseq(toincludeabn.getDataFromId());
            tsAttachmentModel.setPripid(toincludeabn.getPripid());
            tsAttachmentModel.setFileext(file.getContentType());
            fileName = toincludeabn.getDataFromId() + fileName;
            tsAttachmentModel.setFilename(fileName);
            tsAttachmentModel.setLauptime(LocalDateTime.now());
            tsAttachmentModel.setAttachtype("3");
            tsAttachmentModel.setUploaddate(LocalDate.now());
            // 转换特殊数据
            String realPath = CommonConfig.getUploadPathByDate();
            String uploadPath = realPath + File.separator + "abnormal";
            InputStream in = null;
            try {
                if (StringUtils.isNotBlank(file.getContent())) {
                    in = Base64Utils.base64ToInputStream(file.getContent());
                    // 上传ftp
                    Boolean rs = fileStorageService.writeFromStream(uploadPath, fileName, in);
                    if (rs) {
                        String tempPath = uploadPath + File.separator + fileName;
                        // 更新temppath字段
                        tsAttachmentModel.setTemppath(tempPath);
                        tsAttachmentModel.setLauptime(LocalDateTime.now());
                    }
                    save(tsAttachmentModel);
                } else return false;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

    @Override
    public IPage<AttachmentWritDto> selectWritsListzx(Page<AttachmentWritDto> page, AttachmentWritDto attachmentWritDto) {
        return baseMapper.selectWritsListzx(page, attachmentWritDto);
    }

    @Override
    public void getMaterial(HttpServletResponse response, String id, String bizSeqNo, String attachType) throws IOException {
        LambdaQueryWrapper<TSAttachment> queryWrapper = new LambdaQueryWrapper<>();
        if(StringUtils.isNotBlank(id)){
            queryWrapper.eq(TSAttachment::getAttachmentid, id);
        } else {
            queryWrapper.eq(TSAttachment::getBizseq, bizSeqNo)
                    .eq(TSAttachment::getAttachtype, attachType)
                    .orderBy(true,false,TSAttachment::getLauptime)
                    .last("limit 1");
        }
        TSAttachment xrAttachment = this.getOne(queryWrapper);
        if (xrAttachment != null) {
            response.setHeader("Content-Disposition",
                    "attachment;  filename=\"" + new String(xrAttachment.getFilename().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1) + "\"");
            if (StringUtils.equals(xrAttachment.getCreatetype(), "2")){
//                ftpClientFile.writeToStream(xrAttachment.getFileUrl(), response.getOutputStream());
                ftpUtil.getFtpFile(response,xrAttachment.getFileurl());
            } else{
                fileStorageService.writeToStream(xrAttachment.getFileurl(), response.getOutputStream());
                //改用SFTP
//                try {
//                    sftpUtil.download(xrAttachment.getFileurl(), response.getOutputStream());
//                } catch (SftpException e) {
//                    throw new RuntimeException(e);
//                }
            }
        } else {
            throw new RuntimeException("无此上传材料");
        }
    }

    @Override
    public TSAttachment getByBizseqAndType(String bizseq, String attachtype) {
        return getOne(new LambdaQueryWrapper<TSAttachment>().eq(TSAttachment::getBizseq, bizseq).eq(TSAttachment::getAttachtype, attachtype));
    }
}
