package com.gree.mall.manager.logic.comlist;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.client.config.utils.IOUtils;
import com.alibaba.nacos.common.util.UuidUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.commonmapper.CommonMapper;
import com.gree.mall.manager.enums.admin.AdminWebsitTypeEnum;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.AdminWebsitService;
import com.gree.mall.manager.plus.service.ComDetailLogService;
import com.gree.mall.manager.plus.service.ComDetailService;
import com.gree.mall.manager.plus.service.ComListService;
import com.gree.mall.manager.utils.CommonUtils;
import com.gree.mall.manager.utils.DateUtils;
import com.gree.mall.manager.utils.excel.ExcelUtils;
import com.gree.mall.manager.utils.oss.OSSUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

@Slf4j
@Service
public class ComListAllLogic {

    @Autowired
    CommonLogic commonLogic;
    @Autowired
    OSSUtil ossUtil;

    @Autowired
    ComDetailService comDetailService;
    @Autowired
    ComListService comListService;
    @Autowired
    ComDetailLogService comDetailLogService;
    @Autowired
    CommonMapper commonMapper;
    @Autowired
    AdminWebsitService adminWebsitService;


    public IPage<ComList> list(String title, String remark, Boolean isNotice, Integer pageNo, Integer pageSize, HttpServletRequest request) {
        AdminUserCom adminUser = commonLogic.getAdminUser(request);

        List<ComDetail> comDetails = comDetailService.lambdaQuery()
                .select(ComDetail::getComListId)
                .in(CollectionUtil.isNotEmpty(adminUser.getAdminWebsitIds()), ComDetail::getWebsitId, adminUser.getAdminWebsitIds())
                .list();
        List<String> comListIds = comDetails.stream().map(ComDetail::getComListId).collect(Collectors.toList());
        if (comListIds.size() == 0) {
            return new Page<>(pageNo, pageSize);
        }

        IPage<ComList> page = comListService.lambdaQuery()
                //.eq(StringUtils.isNotEmpty(admin.getBelongCompany()),ComList::getBelongCompany,admin.getBelongCompany())
                .in(ComList::getId, comListIds)
                .eq(isNotice != null, ComList::getIsNotice, isNotice)
                .like(StringUtils.isNotEmpty(title), ComList::getTitle, title)
                .like(StringUtils.isNotEmpty(remark), ComList::getRemark, remark)
                .eq( ComList::getType, "FILE")
                .orderByDesc(ComList::getCreateTime)
                .page(new Page<>(pageNo, pageSize));
        //不返回密码
        page.getRecords().forEach(v -> v.setDownloadPwd(""));
        return page;
    }

    public void delete(String id, HttpServletRequest request) {

        AdminUserCom adminUser = commonLogic.getAdminUser(request);
        if (adminUser.getType() == 0) {
            throw new RemoteServiceException("暂无权限");
        }
        comListService.removeById(id);
        comDetailService.lambdaUpdate().eq(ComDetail::getComListId, id).remove();
    }

    public void yonge(String title, String remark, String file, Boolean isNotice, String downloadPwd, HttpServletRequest request) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser(request);

        Map<String, String> map = new HashMap<>();
        ComList comList = new ComList();
        comList.setCompanyWechatId(adminUser.getCompanyWechatId());
        comList.setCompanyName(adminUser.getCompanyName());
        comList.setTitle(title);
        comList.setRemark(remark);
        comList.setFileName(title);
        comList.setIsNotice(isNotice);
        comList.setDownloadPwd(downloadPwd);
        comList.setIsPwd(StringUtils.isNotBlank(downloadPwd));
        comList.setOperatorUserName(adminUser.getUserName());
        comList.setOperatorNickName(adminUser.getNickName());
        comList.setCreateTime(new Date());
        comList.setType("FILE");
        comList.insert();

        //新增拆分的附件明细表
        ComDetail bean = new ComDetail();
        bean.setCompanyWechatId(adminUser.getCompanyWechatId());
        bean.setCompanyName(adminUser.getCompanyName());
        bean.setTitle(title);
        bean.setComListId(comList.getId());
        bean.setFileName(title);
        bean.setWebsitId(adminUser.getUserName());
        bean.setFileUrl(file);
        bean.setIsDownload(false);
        bean.setCreateTime(new Date());
        bean.setIsNotice(comList.getIsNotice());
        bean.insert();

        map.put(comList.getCompanyName(), comList.getId());

        //上传主文件到oss,并记录


       // String url = ossUtil.getUrl(file);

        List<Map<String, Object>>  fileUrls = this.urlToMultipartFile(file,"test.zip");

        List<ComDetail> comDetails = new ArrayList<>();
        for (Map<String, Object> fileUrl : fileUrls) {
            String websitNumber = (String) fileUrl.get("websitNumber");
            String filePath = (String) fileUrl.get("filePath");
            //新增拆分的附件明细表
            //for(Belongcompany belongcompany : list) {
            ComDetail comDetail = new ComDetail();
            comDetail.setCompanyWechatId(adminUser.getCompanyWechatId());
            comDetail.setCompanyName(adminUser.getCompanyName());
            comDetail.setTitle(title);
            comDetail.setComListId(map.get(comDetail.getCompanyName()));
            comDetail.setFileName(title);
            comDetail.setWebsitId(websitNumber);
            comDetail.setFileUrl(filePath);
            comDetail.setIsDownload(false);
            comDetail.setCreateTime(new Date());
            comDetail.setIsNotice(comList.getIsNotice());
            //comDetail.insert();
            comDetails.add(comDetail);
            //}
        }
        comDetailService.saveBatch(comDetails);
    }



/*


    private List<Map<String, Object>> create(MultipartFile zip) {
        try {

            // 获取上传的zip文件流
            InputStream inputStream = zip.getInputStream();
            // 创建ZipArchiveInputStream对象
            ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(inputStream);
            // 创建解压后的文件目录
            File destDir = new File("/Users/dest/");
            if (!destDir.exists()) {
                destDir.mkdir();
            }
            // 循环遍历压缩文件中的所有文件
            ArchiveEntry archiveEntry;
            while ((archiveEntry = zipInputStream.getNextEntry()) != null) {
                String entryName = archiveEntry.getName();
                String[] entryNameParts = entryName.split("/");
                String fileName = entryNameParts[entryNameParts.length - 1];
                File entryFile = new File(destDir + "/" + fileName);
                // 如果是文件夹，就创建文件夹
                if (entryName.endsWith("/")) {
                    entryFile.mkdir();
                } else {
                    // 创建文件输出流
                    OutputStream outputStream = new FileOutputStream(entryFile);
                    // 将压缩文件解压到指定文件
                    byte[] buffer = new byte[1024];
                    int len;
                    while ((len = zipInputStream.read(buffer)) > 0) {
                        outputStream.write(buffer, 0, len);
                    }
                    // 关闭文件输出流
                    outputStream.close();
                }
            }
            // 关闭ZipInputStream
            zipInputStream.close();


            Map<String, List<List<Object>>> map = new HashMap<>();
            log.info("【中心下发文件1】" + DateUtils.formatDate(new Date()));
            for (int i = 1; i < datas.size(); i++) {
                List<Object> row = (List<Object>) datas.get(i);
                CommonUtils.initList2(row, row.size() + 1);
                //网点编号
                String websitNumber = (String) row.get(1);

                List<List<Object>> objects = map.get(websitNumber);
                if (objects == null) {
                    objects = new ArrayList<>();
                }
                //row.remove(0);
                objects.add(row);

                if (!map.containsKey(websitNumber)) {
                    map.put(websitNumber, objects);
                }
            }
            log.info("【中心下发文件2】" + DateUtils.formatDate(new Date()));
            List<Map<String, Object>> fileUrls = new ArrayList<>();
            for (String websitNumber : map.keySet()) {
                //String filePath = "B:/"+email+"-"+file.getName()+".xlsx";
                long currentTime = System.currentTimeMillis();
                String filePath = OSSUtil.OSS_TYPE_PIC + websitNumber + currentTime + ".csv";
                //executorService.submit( ()->{
//                    try {
//                ExcelData excelData = new ExcelData();
//                excelData.setTitles(tableHeaders);
//                excelData.setRows(map.get(websitNumber));

                this.write(filePath, tableHeaders, map.get(websitNumber));
//                    } catch (IOException e) {
//                        log.error("上传文件失败",e);
//                    }
                //});
                Map<String, Object> mp = new HashMap<>();
                mp.put("websitNumber", websitNumber);
                mp.put("filePath", filePath);
                fileUrls.add(mp);
            }
            log.info("【中心下发文件3】" + DateUtils.formatDate(new Date()));
            return fileUrls;
        } catch (Exception e) {
            log.error("【创建excel失败】", e);
        }
        return null;
    }
*/

    public List<Map<String, Object>>  urlToMultipartFile(String fulUrl, String name) throws Exception {

        InputStream inputStream = commonLogic.getFileInputStreamByUrl(fulUrl);


        ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(inputStream);
        ZipEntry entry;


        List<Map<String, Object>> fileUrls = new ArrayList<>();

        while ((entry = zipInputStream.getNextZipEntry())!= null){
            System.out.println("name"+entry.getName());

            File fileZip = FileUtil.touch("testZip/"+entry.getName());

            FileOutputStream fileOutputStreamV = new FileOutputStream(fileZip.getPath());

            byte[] bufferv = new byte[1024];
            int byteRead;
            while((byteRead = zipInputStream.read(bufferv)) != -1){
                fileOutputStreamV.write(bufferv,0,byteRead);
            }

            ossUtil.uploadFile(fileZip.getName(),fileZip);

            String[] s = fileZip.getName().split("_");

            if (s.length < 3)
                throw new RemoteServiceException("导入格式错误");


            List<AdminWebsit> adminWebsits = adminWebsitService.lambdaQuery().in(AdminWebsit::getName, s[2]).list();

            if (CollectionUtils.isEmpty(adminWebsits)){
                throw new RemoteServiceException(s[2]+"找不到对应网点");
            }

            AdminWebsit adminWebsit = adminWebsits.get(0);

            String ossUrl = ossUtil.getAccessUrl() + fileZip.getName();

            Map<String, Object> mp = new HashMap<>();
            mp.put("websitNumber", adminWebsit.getWebsitNumber());
            mp.put("filePath", ossUrl);
            fileUrls.add(mp);


            fileZip.delete();
            fileOutputStreamV.close();

        }

        inputStream.close();
        zipInputStream.close();


        return fileUrls;
    }

    public void download(String id, String downloadPwd, HttpServletRequest request, HttpServletResponse response) throws IOException {
        AdminUserCom adminUser = commonLogic.getAdminUser(request);
        ComList comList = comListService.getById(id);
        if (comList.getIsPwd() && !StringUtils.equals(comList.getDownloadPwd(), downloadPwd)) {
            throw new RemoteServiceException("下载密码校验失败，请联系相关人员");
        }
        log.info("【中心文件下发下载】:{}", JSONObject.toJSONString(adminUser));
        List<ComDetail> comDetails = comDetailService.lambdaQuery()
                .eq(ComDetail::getComListId, id)
                .in(ComDetail::getWebsitId, adminUser.getAdminWebsitIds())
                .list();

        if (CollectionUtils.isEmpty(comDetails)) {
            throw new RemoteServiceException("暂无您可下载的内容");
        }
        this.download(comDetails, adminUser,response);
    }


    private void download(List<ComDetail> comDetails, AdminUserCom admin, HttpServletResponse response) throws IOException {
        String title = comDetails.get(0).getTitle();

        final List<AdminWebsit> websitList = adminWebsitService.lambdaQuery()
                .eq(AdminWebsit::getCompanyWechatId, admin.getCompanyWechatId())
                .eq(AdminWebsit::getType, AdminWebsitTypeEnum.C.getKey())
                .in(AdminWebsit::getWebsitId, admin.getAdminWebsitIds())
                .list();

        final Map<String, String> websitMap = websitList.stream().collect(Collectors.toMap(AdminWebsit::getWebsitId, AdminWebsit::getName));

        for (ComDetail comDetail : comDetails) {
            ComDetailLog comDetailLog = new ComDetailLog();
            comDetailLog.setCompanyWechatId(admin.getCompanyWechatId());
            comDetailLog.setCompanyName(admin.getCompanyName());
            comDetailLog.setCreateTime(new Date());
            comDetailLog.setComListId(comDetail.getComListId());
            comDetailLog.setTitle(comDetail.getTitle());
            comDetailLog.setUserName(admin.getUserName());
            comDetailLog.setWebsitId(comDetail.getWebsitId());
            comDetailLog.setWebsitName(websitMap.get(comDetail.getWebsitId()));
            comDetailLog.setIsNotice(comDetail.getIsNotice());
            comDetailLog.insert();
        }
        List<Map<String, Object>> files = new ArrayList<>();
        //String fileUrl = comDetail.getFileUrl();
        for (ComDetail comDetail : comDetails) {
            if (StringUtils.isEmpty(comDetail.getWebsitId())) {
                continue;
            }
            Map<String, Object> map = new HashMap<>();
            map.put("fileUrl", comDetail.getFileUrl());
            map.put("fileName", comDetail.getFileUrl().split("/")[3]);
            files.add(map);
        }
        if (files.size() > 1) {
            CommonUtils.writeZip(response, files);
        } else {
            CommonUtils.downloadFile(files.get(0).get("fileUrl").toString(),files.get(0).get("fileName").toString() , response);
        }
        //CommonUtils.downloadFile(imgFile,admin.getWebsitNumber()+"-"+comDetail.getTitle()+".csv",response);
        //return imgFile;
    }


    public IPage<ComDetailLog> logList(String id, Integer pageNo, Integer pageSize, HttpServletRequest request) {
        AdminUserCom adminUser = commonLogic.getAdminUser(request);

        IPage<ComDetailLog> page = comDetailLogService.lambdaQuery()
                .in(CollectionUtil.isNotEmpty(adminUser.getAdminWebsitIds()), ComDetailLog::getWebsitId, adminUser.getAdminWebsitIds())
                .eq(Objects.nonNull(adminUser.getAdminCompanyWechat()), ComDetailLog::getCompanyWechatId, adminUser.getCompanyWechatId())
                .eq(ComDetailLog::getComListId, id)
                .orderByDesc(ComDetailLog::getCreateTime)
                .page(new Page<>(pageNo, pageSize));
        return page;
    }
}
