package com.sunxung.factoring.service.sys.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.sunxung.factoring.component.config.FileUploadProperties;
import com.sunxung.factoring.component.enums.FileBusinessInterface;
import com.sunxung.factoring.component.enums.FileStorageTypeEnum;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.util.CodeUtil;
import com.sunxung.factoring.component.util.FileStorageUtil;
import com.sunxung.factoring.component.util.ThreadLocalUtil;
import com.sunxung.factoring.entity.sys.FileStorage;
import com.sunxung.factoring.entity.sys.FileStorageDO;
import com.sunxung.factoring.mapper.sys.FileStorageDAO;
import com.sunxung.factoring.service.sys.FileService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;

@Service
public class FileServiceImpl extends ServiceImpl<FileStorageDAO,FileStorageDO> implements FileService {

    @Value("${localhost}")
    private String localhost;

    @Autowired
    private FileUploadProperties fileUploadProperties;

    public static final String FILE_NAME = "file";

    @Override
    public FileStorageDO uploadFile(HttpServletRequest request, FileBusinessInterface fileBusinessEnum) {
        if (fileBusinessEnum == null) {
            throw new BusinessException(CodeUtil.FAIL,"获取文件错误");
        }
        if (request instanceof MultipartHttpServletRequest) {
            MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
            MultipartFile multipartFile = multipartHttpServletRequest.getFile(FILE_NAME);
            if (multipartFile == null) {
                return null;
            }
            FileStorageDO fileStorage = FileStorageUtil.createFileStorage(multipartFile, fileBusinessEnum);
            fileStorage.setStorageType(FileStorageTypeEnum.DISK.getCode());
            //文件存储到本地
            try {
                String absolutePath = fileStorage.getAbsolutePath();
                File file = new File(absolutePath);
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }
                multipartFile.transferTo(file);

//                //将精准评估照片上传至oss
//                if (FileTypeEnum.PRECISE_ASSESS_VIDEO.getCode().equals(fileBusinessEnum.getCode()) ||
//                    FileTypeEnum.PRECISE_ASSESS_PHOTOS.getCode().equals(fileBusinessEnum.getCode())){
//                    String filePath = fileStorage.getPath();
//                    filePath = filePath.replace("\\", "/");
//                    OSSUtil.uploadFile(fileStorage.getAbsolutePath(),filePath);
//                    fileStorage.setPath(OSSUtil.getUrl(filePath));
//                    fileStorage.setStorageType(FileStorageTypeEnum.OSS.getCode());
//                }
                this.save(fileStorage);
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException(CodeUtil.FAIL, "文件上传失败");
            }
            return fileStorage;

        }
        throw new BusinessException(CodeUtil.FAIL, "获取文件错误");
    }

    @Override
    public List<FileStorageDO> uploadFiles(HttpServletRequest request, List<FileBusinessInterface> list) {
        List<FileStorageDO> returnList = Lists.newArrayList();
        if (request instanceof MultipartHttpServletRequest) {
            MultiValueMap<String, MultipartFile> multiValueMap = ((MultipartHttpServletRequest) request)
                    .getMultiFileMap();
            if (CollectionUtil.isEmpty(multiValueMap.values())) {
                throw new BusinessException(CodeUtil.FAIL, "获取文件错误");
            }
            if (CollectionUtil.isEmpty(list)) {
                return null;
            }
            for (FileBusinessInterface fbi : list) {
                String code = fbi.getCode();
                List<MultipartFile> multipartFiles = multiValueMap.get(code);
                if (CollectionUtil.isNotEmpty(multipartFiles)) {
                    for (MultipartFile multipartFile : multipartFiles) {
                        FileStorageDO fileStorage = FileStorageUtil.createFileStorage(multipartFile, fbi);
                        //文件存储到本地
                        try {
                            multipartFile.transferTo(new File(fileStorage.getAbsolutePath()));
                            this.save(fileStorage);
                        } catch (IOException e) {
                            e.printStackTrace();
                            throw new BusinessException(CodeUtil.FAIL, "文件上传失败");
                        }
                        returnList.add(fileStorage);
                    }
                }

            }

        }
        return returnList;
    }

    @Override
    public List<FileStorageDO> findByBusinessId(Long businessId, String businessType) {
        LambdaQueryWrapper<FileStorageDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FileStorageDO::getBusinessId, businessId);
        if (!StringUtils.isEmpty(businessType)) {
            lambdaQueryWrapper.eq(FileStorageDO::getBusinessType, businessType);
        }
        List<FileStorageDO> fileStorageDOS = this.baseMapper.selectList(lambdaQueryWrapper);
//        if (!CollectionUtils.isEmpty(fileStorageDOS)) {
//            List<FileStorageDTO> returnList = Lists.newArrayList();
//            for (FileStorageDO fs : fileStorageDOS) {
//                FileStorageDTO fileStorageDTO = BeanUtilsProxy.copyProperties(fs,
//                        FileStorageDTO.class);
//                String storageType = fileStorageDTO.getStorageType();
//                if (FileStorageTypeEnum.DISK.getCode().equals(storageType)) {
//                    String filePath = localhost + fileUploadProperties.getResourcePath() + fileStorageDTO.getPath();
//                    filePath = filePath.replace("\\", "/").replace("*", "");
//                    fileStorageDTO.setPath(filePath);
//                }
////                if(FileStorageTypeEnum.OSS.getCode().equals(storageType)){
////                    fileStorageDTO.setPath(OSSUtil.getUrl(fileStorageDTO.getPath()));
////                }
//                returnList.add(fileStorageDTO);
//
//            }
//            return returnList;
//        }
        return fileStorageDOS;
    }

    @Override
    public FileStorageDO findOneByBusinessId(Long businessId, String businessType) {
        LambdaQueryWrapper<FileStorageDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FileStorageDO::getBusinessId, businessId)
                .eq(FileStorageDO::getBusinessType, businessType);
        lambdaQueryWrapper.last("limit 1");
        lambdaQueryWrapper.orderByDesc(FileStorageDO::getId);
        FileStorageDO fileStorageDO = this.baseMapper.selectOne(lambdaQueryWrapper);
//        FileStorageDTO fileStorageDTO = BeanUtilsProxy.copyProperties(fileStorageDO,
//                FileStorageDTO.class);
//        if (fileStorageDTO != null) {
//            String storageType = fileStorageDTO.getStorageType();
//            if (FileStorageTypeEnum.DISK.getCode().equals(storageType)) {
//                String filePath = localhost + fileUploadProperties.getResourcePath() + fileStorageDTO.getPath();
//                filePath = filePath.replace("\\", "/").replace("*", "");
//                fileStorageDTO.setPath(filePath);
//            }
//            if(FileStorageTypeEnum.OSS.getCode().equals(storageType)){
//                String path = fileStorageDTO.getPath();
//                String newPath = path.replace("\\", "/");
//                fileStorageDTO.setPath(OSSUtil.getUrl(newPath));
//            }
//        }
        return fileStorageDO;
    }

    @Override
    public void updateBusinessId(List<Long> fileIds, Long businessId) {
        if (CollectionUtil.isNotEmpty(fileIds)) {
            lambdaUpdate().in(FileStorageDO::getId, fileIds).set(FileStorageDO::getBusinessId, businessId).update();
        }
    }

    @Override
    public void updateBusinessId(Long fileId, Long businessId) {
        if (fileId != null) {
            lambdaUpdate().eq(FileStorageDO::getId, fileId).set(FileStorageDO::getBusinessId, businessId).update();
        }
    }

    /**
     * 该接口 只能删除 图片上传人 和  操作人 一致的 数据
     * 删除id
     *
     * @param id
     */
    @Override
    public void delete(Long id) {
        Long userId = ThreadLocalUtil.getUserId();
        FileStorageDO one = this.lambdaQuery().eq(FileStorageDO::getId, id).eq(FileStorageDO::getUserCreate, userId).one();
        if (one == null) {
            throw new BusinessException(CodeUtil.FAIL,"获取不到对应文件");
        }
        this.baseMapper.deleteById(one);
    }

    @Override
    public ResponseEntity<Object> downloadFile(Long id,HttpServletResponse res) {
        FileStorageDO fileStorage = this.getById(id);
        if (fileStorage != null) {
            String fileName = fileStorage.getOriginalName();
            String path = fileStorage.getAbsolutePath();
            File file = new File(path);
            try {
                if (file.exists()) {
                    fileName = new String(fileName.getBytes("UTF-8"));
                    String basePath = file.getAbsolutePath();
                    InputStream in = new FileInputStream(new File(basePath));
                    fileName = URLEncoder.encode(fileName, "UTF-8");
//                res.setHeader("content-disposition", "attachment;filename=" + fileName);
//                res.setHeader("Content-Type", "application/vnd.ms-exce");
                    res.setHeader("Content-Disposition", "attachment;filename=" + fileName);
                    res.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
                    OutputStream out = res.getOutputStream();
                    byte[] b = new byte[1024];
                    int len = -1;
                    while ((len = in.read(b)) != -1) {
                        out.write(b, 0, len);
                        out.flush();
                    }
                    // 关闭
                    in.close();
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}
