package com.bonus.sgzb.system.service.impl;

import cn.hutool.core.util.IdUtil;
import com.bonus.sgzb.common.core.constant.HttpStatus;
import com.bonus.sgzb.common.core.utils.DateTimeHelper;
import com.bonus.sgzb.common.core.utils.GlobalConstants;
import com.bonus.sgzb.common.core.web.domain.AjaxResult;
import com.bonus.sgzb.common.security.utils.SecurityUtils;
import com.bonus.sgzb.system.domain.FileInfo;
import com.bonus.sgzb.system.mapper.FileInfoMapper;
import com.bonus.sgzb.system.service.SysFileService;
import com.bonus.sgzb.system.service.feign.FileClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.*;

/**
 * 本地文件存储
 *
 * @author zys
 */
@Slf4j
@Primary
@Service("SysFileService")
public class SysFileServiceImpl implements SysFileService {

    @Resource
    private FileInfoMapper dao;
    /**
     * 上传文件存储在本地的根路径
     */
    @Value("${file.path}")
    private String localFilePath;

    // 允许的文件格式
    private static final List<String> ALLOWED_EXTENSIONS = Arrays.asList("jpg", "jpeg", "txt", "png", "pdf", "docx", "doc", "xlsx", "xls");

    @Resource
    private FileClient fileClient;


    /**
     * 本地文件上传接口
     *
     * @return 访问地址
     * @throws Exception
     */
    @Override
    public FileInfo uploadFile(HttpServletRequest request) throws Exception {
        FileInfo file = new FileInfo();
        StandardMultipartHttpServletRequest req = (StandardMultipartHttpServletRequest) request;
        String photoType = req.getParameter("fileType");
        Long userId = SecurityUtils.getLoginUser().getUserid();
        HashMap<String, Object> map = getFile(req);
        List<MultipartFile> items = (List<MultipartFile>) map.get("filePath");
        MultipartFile item = items.get(0);
        // 获取文件后缀名
        String fileExtension = item.getOriginalFilename().substring(item.getOriginalFilename().lastIndexOf(".") + 1);
        if (!ALLOWED_EXTENSIONS.contains(fileExtension.toLowerCase())) {
            throw new Exception("不支持该文件格式");
        }
        // 检查文件大小
        long fileSize = item.getSize();
        long maxSize = 20 * 1024 * 1024; // 20MB
        if (fileSize > maxSize) {
            throw new Exception("文件太大，请重新上传");
        }
        try {
            String url = saveFile(request, item, photoType);
            //AjaxResult res = fileClient.uploadFile(item);
            //String url = (String) res.get("msg");
            if (url != null) {
                int words = getFileText(item);
                String fileName = item.getOriginalFilename();
                String type = fileName.substring(fileName.lastIndexOf(".") + 1);
                long size = item.getSize() / 1024 / 1024;
                file.setFileName(fileName);
                file.setFileUrl(url);
                file.setCreator(userId.toString());
                file.setType(type);
                file.setSize(size + "M");
                file.setWords(words);
                file.setCreateBy(SecurityUtils.getLoginUser().getUserid().toString());
                file.setCreateTime(new Date());
                dao.insertFileInfo(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return file;
    }

    /**
     * 头像上传
     *
     * @return 访问地址
     * @throws Exception
     */
    @Override
    public FileInfo uploadHeadPic(MultipartFile item, String fileType) {
        FileInfo file = new FileInfo();
        Long userId = SecurityUtils.getLoginUser().getUserid();
        try {
            String url = saveFilePic(item, fileType);
            /*AjaxResult res = fileClient.uploadFile(item);
            String url = (String) res.get("msg");*/
            if (url != null) {
                int words = getFileText(item);
                String fileName = item.getOriginalFilename();
                String type = fileName.substring(fileName.lastIndexOf(".") + 1);
                long size = item.getSize() / 1024 / 1024;
                file.setFileName(fileName);
                file.setFileUrl(url);
                file.setCreator(userId.toString());
                file.setType(type);
                file.setSize(size + "M");
                file.setWords(words);
                file.setCreateBy(SecurityUtils.getLoginUser().getUserid().toString());
                file.setCreateTime(new Date());
                dao.insertFileInfo(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return file;
    }

    public HashMap<String, Object> getFile(StandardMultipartHttpServletRequest request) {
        MultipartFile multipartFile;
        HashMap<String, Object> map = new HashMap<String, Object>(16);
        try {
            List<MultipartFile> tmps = new ArrayList<MultipartFile>();
            Iterator<String> itr = request.getFileNames();
            while (itr.hasNext()) {
                multipartFile = request.getFile(itr.next());
                tmps.add(multipartFile);
            }
            map.put("filePath", tmps);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    public String saveFile(HttpServletRequest request, MultipartFile multipartFile, String fileType) throws Exception {
        String url = "";
        // 完整路径 IE
        String tmpName = multipartFile.getOriginalFilename();
        tmpName = tmpName.substring(tmpName.lastIndexOf("\\") + 1);
        tmpName = IdUtil.fastSimpleUUID() + System.currentTimeMillis() + tmpName.substring(tmpName.lastIndexOf("."), tmpName.length());
        String imageFiles = localFilePath + fileType + "/";
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith(GlobalConstants.STRING_WIN)) {
            imageFiles = "D://files/" + fileType + "/";
        }
        String year = DateTimeHelper.getNowYear();
        String month = DateTimeHelper.getNowMonths();
        String day = DateTimeHelper.getNowDay();
        String specfile = imageFiles + year + "/" + month + "/" + day;
        File file = new File(specfile + "/" + tmpName);

        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        url = "/" + fileType + "/" + year + "/" + month + "/" + day + "/" + tmpName;
        if (!multipartFile.isEmpty()) {
            try {
                FileOutputStream fos = new FileOutputStream(file);
                InputStream in = multipartFile.getInputStream();
                byte[] bytes = new byte[1024];
                int len = 0;
                while ((len = in.read(bytes)) != -1) {
                    fos.write(bytes, 0, len);
                }
                fos.close();
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return url;
    }

    public String saveFilePic(MultipartFile multipartFile, String fileType) throws Exception {
        String url = "";
        // 完整路径 IE
        String tmpName = multipartFile.getOriginalFilename();
        tmpName = tmpName.substring(tmpName.lastIndexOf("\\") + 1);
        tmpName = IdUtil.fastSimpleUUID() + System.currentTimeMillis() + tmpName.substring(tmpName.lastIndexOf("."), tmpName.length());
        String imageFiles = localFilePath + fileType + "/";
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith(GlobalConstants.STRING_WIN)) {
            imageFiles = "D://files/" + fileType + "/";
        }
        String year = DateTimeHelper.getNowYear();
        String month = DateTimeHelper.getNowMonths();
        String day = DateTimeHelper.getNowDay();
        String specfile = imageFiles + year + "/" + month + "/" + day;
        File file = new File(specfile + "/" + tmpName);

        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        url = "/" + fileType + "/" + year + "/" + month + "/" + day + "/" + tmpName;
        if (!multipartFile.isEmpty()) {
            try {
                FileOutputStream fos = new FileOutputStream(file);
                InputStream in = multipartFile.getInputStream();
                byte[] bytes = new byte[1024];
                int len = 0;
                while ((len = in.read(bytes)) != -1) {
                    fos.write(bytes, 0, len);
                }
                fos.close();
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return url;
    }

    private int getFileText(MultipartFile file) throws IOException {
        int length = 0;
        String fileName = file.getOriginalFilename();
        InputStream fileInputStream = file.getInputStream();
        try {
            ZipSecureFile.setMinInflateRatio(-1.0d);
            //获取文件后缀名
            String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
            //定义word内容
            String content = "";
            switch (suffix) {
                case "doc":
                    WordExtractor wordExtractor = new WordExtractor(fileInputStream);
                    content = wordExtractor.getText();
                    break;
                case "docx":
                    XWPFDocument document = new XWPFDocument(fileInputStream);
                    XWPFWordExtractor extractor = new XWPFWordExtractor(document);
                    content = extractor.getText();
                    break;
                default:
                    break;
            }
            //中文单词
            String cnWords = content.replaceAll("[^(\\u4e00-\\u9fa5，。《》？；’‘：“”【】、）（……￥！·)]", "");
            int cnWordsCount = cnWords.length();
            //非中文单词
            String noCnWords = content.replaceAll("[^(a-zA-Z0-9`\\-=\';.,/~!@#$%^&*()_+|}{\":><?\\[\\])]", " ");
            int noCnWordsCount = 0;
            String[] ss = noCnWords.split(" ");
            for (String s : ss) {
                if (s.trim().length() != 0) {
                    noCnWordsCount++;
                }
            }
            length = cnWordsCount + noCnWordsCount;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                fileInputStream.close();
            }
        }
        return length;
    }

}
