package com.jeeplus.assess.assessSignatureDaily.controller;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.jeeplus.assess.assessSignatureDaily.domain.PresignCallBack;
import com.jeeplus.assess.assessSignatureDaily.mapper.AssessSignatureDailyOfficeWorkMapper;
import com.jeeplus.assess.assessSignatureDaily.service.AssessSignatureDailyOfficeWorkService;
import com.jeeplus.assess.assessSignatureDaily.service.dto.AssessSignatureDailyOfficeWorkDTO;
import com.jeeplus.assess.utils.Global;
import com.jeeplus.assess.utils.SignaturePostUtil;
import com.jeeplus.common.redis.RedisUtils;
import com.jeeplus.common.utils.ResponseUtil;

import com.jeeplus.sys.domain.WorkAttachmentInfo;
import com.jeeplus.sys.feign.IUserApi;
import com.jeeplus.sys.feign.IWorkAttachmentApi;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 项目签章回调接口Controller
 * @author 徐滕
 * @version 2021-11-04
 */
@Controller
@RequestMapping(value = "/assessDailyOfficeWork/signatureCallBack")
public class AssessDailyOfficeWorkSignatureCallBackController {
    private static Logger logger = LoggerFactory.getLogger(ResponseUtil.class);
    private static final String DIRECTORY  = Global.getConfig("directory");


    @Autowired
    private AssessSignatureDailyOfficeWorkService dailyOfficeWorkService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private AssessSignatureDailyOfficeWorkMapper signatureDailyOfficeWorkMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

//    private final DailyOfficeWorkDao dailyOfficeWorkDao = SpringContextHolder.getBean(DailyOfficeWorkDao.class);

    @ModelAttribute
    public AssessSignatureDailyOfficeWorkDTO get(@RequestParam(required=false) String id) {
        AssessSignatureDailyOfficeWorkDTO entity = null;
        if (StringUtils.isNotBlank(id)){
            entity = dailyOfficeWorkService.findById(id);
        }
        if (entity == null){
            entity = new AssessSignatureDailyOfficeWorkDTO();
        }
        return entity;
    }

    /**
     * 审定单签章回调操作
     * @param presignCallBack  回调参数
     * @return
     */
    @RequestMapping(value = "/getDailyOfficeWorkCoordinates", method= RequestMethod.POST)
    public String getDailyOfficeWorkCoordinates(PresignCallBack presignCallBack, HttpServletRequest request , HttpServletResponse response) {
        long t1 = System.currentTimeMillis();
        //根据contractId查询对应的报告信息
        String[] documentIds = presignCallBack.getDocumentId().split(",");

        //根据contractId查询对应的报告信息
        AssessSignatureDailyOfficeWorkDTO dailyOfficeWork = dailyOfficeWorkService.getByDocumentId(documentIds[0]);

        if("5".equals(dailyOfficeWork.getStatus()) ){
            return null;
        }

        if(StringUtils.isBlank(presignCallBack.getContractId())){

            return null;
        }
        //修改签章信息
        //签章完成则进行数据的保存
        dailyOfficeWork.setSignatureFlag(1);
        dailyOfficeWork.setSignatureContractId(presignCallBack.getContractId());
        dailyOfficeWork.setSignatureUploadDate(new Date());
        //对文件回调路径进行处理并保存
        String signatureUrl = null;
        if(StringUtils.isNotBlank(presignCallBack.getStoragePath())){
            signatureUrl = presignCallBack.getStoragePath().replace("oss:/","");
            //必须得再进行一次替换,否则无法下载到本地
            signatureUrl = signatureUrl.replace("/xg-qz","");
            dailyOfficeWork.setSignatureUrl(signatureUrl);
            dailyOfficeWork.setSignatureUrlFlag(1);

            String input = signatureUrl;
            int lastSlashIndex = input.lastIndexOf('/');
            int lastDotIndex = input.lastIndexOf('.');

            // 检查是否存在 / 和 .，以及 . 是否在 / 之后
            if (lastSlashIndex != -1 && lastDotIndex != -1 && lastSlashIndex < lastDotIndex) {
                String result = input.substring(lastSlashIndex + 1, input.length());
                //添加文件名称
                dailyOfficeWork.setSignatureFileName(result);
            }
            UserDTO userDTO = SpringUtil.getBean(IUserApi.class).getUserDTOByName("管理员");
            dailyOfficeWork.setSignatureUploadFileUser(userDTO);

        }
        //修改签章对应信息文件
        signatureDailyOfficeWorkMapper.updateSignatureInfo(dailyOfficeWork);
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getById (dailyOfficeWork.getCreateById());
        //将文件下载并对原有文件地址进行替换
        String deleteFile = null;
        String unzipFileStr = null;
        try{
            String path = null;
            if(System.getProperty("os.name").toLowerCase().contains("win")){
                path = "D:/attachment-file/";
            }else{
                path = "/attachment-file/";
            }
            String aliyunUrl = "http://cdn.gangwaninfo.com";
            String aliDownloadUrl = "http://oss.gangwaninfo.com";


            String file = aliyunUrl + signatureUrl;
            file = file.replace("amp;","");
            String fileName = file.substring(file.lastIndexOf("/") + 1, file.length());
            String cons = "";
            if (file.contains(aliyunUrl)){
                cons = aliyunUrl;
            }else if (file.contains("http://gangwan-app.oss-cn-hangzhou.aliyuncs.com")){
                cons = "http://gangwan-app.oss-cn-hangzhou.aliyuncs.com";
            }else {
                cons = aliDownloadUrl;
            }
            String ossKey = file.split(cons+"/")[1];
            SpringUtil.getBean ( IWorkAttachmentApi.class ).downQzByStreamSaveLocal(ossKey,fileName,path+fileName);
//            ossClientService.downQzByStreamSaveLocal(ossKey,fileName,path+fileName);
            //将下载下来的文件转换为file文件
            File srcFile = new File(path+fileName);
            deleteFile = path+fileName;

            //截取文件名称
            String srcFileName = srcFile.getName().substring(0,srcFile.getName().lastIndexOf("."));

            //解压后文件地址
            unzipFileStr = path + srcFileName;

            //将下载后的文件进行解压
            SignaturePostUtil.unZipFile(srcFile,unzipFileStr);

            //遍历解压后文件夹中的所有文件信息
            File unZipFile = new File(unzipFileStr);

            File[] unZipFileList = unZipFile.listFiles();

            if(null != unZipFileList && unZipFileList.length>0){
                for (File f : unZipFileList) {
                    String filepath = "";
                    //取得上传文件
                    //将文件上传到oss云盘中
                    MultipartFile cMultiFile = new MockMultipartFile("file", f.getName(), null, new FileInputStream(f));
                    if (!cMultiFile.isEmpty()) {
                        // 文件保存路径
                        String realPath =DIRECTORY.replaceFirst("/","")+"/cw_signature_daily_file"+SpringUtil.getBean ( IWorkAttachmentApi.class ).datePath()+"/"+ System.currentTimeMillis();
                        //文件原名称
                        String newName = cMultiFile.getOriginalFilename();
                        if(org.apache.commons.lang3.StringUtils.isNotBlank(newName)){
                            newName = newName.substring(13, newName.length());
                            //SpringUtil.getBean ( IWorkAttachmentApi.class ).uploadFile2OSS(cMultiFile.getInputStream(),realPath,newName);
                            SpringUtil.getBean ( IWorkAttachmentApi.class ).uploadFileSignatureOSS(f.getPath(),realPath,newName);
                            filepath = "/" + realPath + newName;
                        }
                    }

                    System.out.println(f.getName());
                    //截取文件后缀名
                    String substring = f.getName().substring(f.getName().lastIndexOf(".")+1, f.getName().length());

                    String newFileName = f.getName().substring(13, f.getName().length());

                    //将签章完成的附件进行保存到附件表中
                    WorkAttachmentInfo workattachment = new WorkAttachmentInfo();
                    workattachment.setDelFlag(0);
                    workattachment.setUrl(filepath);
                    workattachment.setType(substring);
                    workattachment.setAttachmentName(newFileName);
                    workattachment.setAttachmentFlag("signatured_daily");
                    workattachment.setFileSize(String.valueOf(f.length()));
                    workattachment.setAttachmentId(dailyOfficeWork.getId());
                    workattachment.setAttachmentType("");
                    String id = UUID.randomUUID().toString().replace("-", "");
                    workattachment.setId(id);
                    workattachment.setCreateTime(new Date());
                    workattachment.setUpdateTime(new Date());
                    //先查询数据库中是否已经对数据进行保存
                    //若未保存，则进行保存，否则直接跳过
                    List<WorkAttachmentInfo> byAttachmentIdAndUrl = SpringUtil.getBean ( IWorkAttachmentApi.class ).getByAttachmentIdAndUrlAndAttachmentFlag(workattachment);
                    if(byAttachmentIdAndUrl.size() == 0){
                        Map<String,String> map = new HashMap<>();
                        String workAttachment = JSON.toJSONString((workattachment));
                        String userDTOInfo = JSON.toJSONString((userDTO));
                        map.put("workAttachment",workAttachment);
                        map.put("userDTO",userDTOInfo);
                        SpringUtil.getBean ( IWorkAttachmentApi.class ).insertWorkAttachment(map);
//                        ossServiceMapper.insert(workattachment);

                        //将附件信息添加到签章附件信息表中
//                        CwSignatureDailyFile cwSignatureDailyFile = new CwSignatureDailyFile();
//                        cwSignatureDailyFile.setDelFlag(0);
//                        cwSignatureDailyFile.setId(UUID.randomUUID().toString().replace("-", ""));
//                        cwSignatureDailyFile.setCreateById(dailyOfficeWork.getCreateById());
//                        cwSignatureDailyFile.setUpdateById(dailyOfficeWork.getCreateById());
//                        cwSignatureDailyFile.setCreateTime(new Date());
//                        cwSignatureDailyFile.setUpdateTime(new Date());
//                        cwSignatureDailyFile.setReportFileId(id);
//                        cwSignatureDailyFile.setFileAffiliation("1");
//                        signatureDailyOfficeWorkMapper.insertFile(cwSignatureDailyFile);
                    }

                    //遍历该contractId对应的报告信息，将报告信息中的附件地址进行替换

                    //查询报告文件信息（电子章）
                    /*List<WorkAttachment> fileList = attachmentMapper.selectWorkAttachmentByReportId(projectReportData.getId());
                    if(fileList.size()>0){
                        for (WorkAttachment workattachment : fileList) {
                            //根据url截取文件名成
                            String workattachmentName = workattachment.getUrl().substring(workattachment.getUrl().lastIndexOf("/")+1, workattachment.getUrl().length());

                            if(f.getName().contains(workattachmentName)){
                                workattachment.setUrl(filepath);
                                workattachment.setType(substring);
                                workattachment.setAttachmentName(f.getName());
                                attachmentMapper.updateByIdOnSignature(workattachment);
                            }
                        }
                    }*/
                }
            }

            //将报告数据中的盖章状态更改为已盖章
            //cwProjectReportService.updateReportSealType(projectReportData);

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(org.apache.commons.lang3.StringUtils.isNotBlank(deleteFile)){
                //根据路径创建文件对象
                File file = new File(deleteFile);
                //路径是个文件且不为空时删除文件
                if(file.isFile()&&file.exists()){
                    file.delete();
                }
            }
            File file = new File(unzipFileStr);
            deleteFile(file);
        }

        return null;
    }

    /**
     * 日常签章每个节点处理方法
     * @param presignCallBack
     * @param response
     * @return
     */
    @RequestMapping(value = "/getDailyOfficeWorkCallBackAccomplish", method= RequestMethod.POST)
    public String getDailyOfficeWorkCallBackAccomplish(PresignCallBack presignCallBack, HttpServletResponse response) {

        //根据contractId查询对应的报告信息
        AssessSignatureDailyOfficeWorkDTO dailyOfficeWork = dailyOfficeWorkService.getByContractId(presignCallBack.getContractId());
        if("5".equals(dailyOfficeWork.getStatus())){
            return null;
        }

        String json = JSON.toJSONString(presignCallBack);
        try {
            String keySign = "dailyOfficeWorkSignatureSign" + dailyOfficeWork.getId();
            String keyStatus = "dailyOfficeWorkSignatureSignStatus" + dailyOfficeWork.getId();

            ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
            operations.set(keySign, json, 1, TimeUnit.DAYS); // 设置有效期为1天
            operations.set(keyStatus, "true", 1, TimeUnit.DAYS); // 设置有效期为1天
        } catch (Exception e) {
            logger.error("Error saving data to Redis", e);
        }
        return null;
    }

    public static Boolean deleteFile(File file) {
        //判断文件不为null或文件目录存在
        if (file == null || !file.exists()) {
            System.out.println("文件删除失败,请检查文件是否存在以及文件路径是否正确");
            return false;
        }
        //获取目录下子文件
        File[] files = file.listFiles();
        //遍历该目录下的文件对象
        for (File f : files) {
            //判断子目录是否存在子目录,如果是文件则删除
            if (f.isDirectory()) {
                //递归删除目录下的文件
                deleteFile(f);
            } else {
                //文件删除
                f.delete();
                //打印文件名
                System.out.println("文件名：" + f.getName());
            }
        }
        //文件夹删除
        file.delete();
        System.out.println("目录名：" + file.getName());
        return true;
    }
}
