package com.lutao.cloud.oil.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONObject;
import com.amazonaws.services.s3.model.S3Object;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lutao.cloud.common.core.util.MessageInfo;
import com.lutao.cloud.common.core.util.ObjectUtil;
import com.lutao.cloud.common.core.util.StringUtil;
import com.lutao.cloud.common.oss.OssProperties;
import com.lutao.cloud.common.oss.service.OssTemplate;
import com.lutao.cloud.common.security.util.SecurityUtils;
import com.lutao.cloud.oil.mapper.UploadFileMapper;
import com.lutao.cloud.oil.pojo.entity.UploadFile;
import com.lutao.cloud.oil.pojo.param.FileParam;
import com.lutao.cloud.oil.service.UploadFileService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.util.Arrays;

@Service
@Slf4j
public class UploadFileServiceImpl extends ServiceImpl<UploadFileMapper, UploadFile> implements UploadFileService {

    @Resource
    private OssProperties ossProperties;

    @Resource
    private OssTemplate minioTemplate;

    /**
     * 上传文件
     * @param file
     * @return
     */
    @Override
    public MessageInfo uploadFile(MultipartFile file) {
        log.info(ossProperties.toString());
        //String fileName = IdUtil.simpleUUID() + StrUtil.DOT + FileUtil.extName(file.getOriginalFilename());
        String fileName = file.getOriginalFilename(); //index.html
        // 获取文件后缀名
        String fileExtension = "";
        if (fileName != null && fileName.contains(".")) {
            fileExtension = fileName.substring(fileName.lastIndexOf('.') + 1);
        }
        if (fileName != null){
            String[] split = fileName.split("\\.");
            log.info(Arrays.toString(split));
            if(split.length>1){
                fileName = split[0]+System.nanoTime()+"."+split[1];
            }
        }

        JSONObject resultJson = new JSONObject();
        resultJson.putOnce("bucketName", ossProperties.getBucketName());
        resultJson.putOnce("fileName", file.getOriginalFilename());
        DecimalFormat df = new DecimalFormat("#0");
        String fileSize = df.format(file.getSize() / 1024);
        resultJson.putOnce("fileSize", fileSize);
        resultJson.putOnce("type",FileUtil.extName(file.getOriginalFilename()));
        resultJson.putOnce("url", String.format("%s/%s", ossProperties.getBucketName(), fileName));
        resultJson.putOnce("fileRealName", fileName);

        try {
            minioTemplate.putObject(ossProperties.getBucketName(), fileName, file.getInputStream());
            // 文件管理数据记录,收集管理追踪文件
            UploadFile uploadFile = new UploadFile();
            uploadFile.setFileName(fileName);
            uploadFile.setFilePath(ossProperties.getBucketName() + "/" + fileName);
            uploadFile.setUploadTime(LocalDateTime.now());
            String nickname = "未获取到上传人";
            if (SecurityUtils.getUser() !=null){
                nickname = SecurityUtils.getUser().getNickname();
            }
            uploadFile.setUploadUser(nickname);
            uploadFile.setBucket(ossProperties.getBucketName());
            uploadFile.setFileSize(fileSize);
            uploadFile.setFileSuffix(fileExtension);
            this.save(uploadFile);
        }
        catch (Exception e) {
            log.error("上传失败", e);
            return MessageInfo.failed(e.getLocalizedMessage());
        }
        return MessageInfo.ok(resultJson);
    }

    /**
     * 读取文件
     * @param bucket
     * @param fileName
     * @param response
     */
    @Override
    public void getFile(String bucket, String fileName, HttpServletResponse response) {
        try (S3Object s3Object = minioTemplate.getObject(bucket, fileName)) {
            response.setContentType("application/octet-stream; charset=UTF-8");
            IoUtil.copy(s3Object.getObjectContent(), response.getOutputStream());
        }
        catch (Exception e) {
            log.error("读取文件失败", e);
        }

    }

    /**
     * 删除文件
     * @param id
     * @return
     */
    @Override
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteFile(Long id) {
        UploadFile file = this.getById(id);
        minioTemplate.removeObject(ossProperties.getBucketName(), file.getFileName());
        return this.removeById(id);
    }

    @Override
    public MessageInfo<IPage<UploadFile>> filePage(Page page, FileParam param) {
        LambdaQueryWrapper<UploadFile> wrapper = Wrappers.lambdaQuery(UploadFile.class)
                .like(StringUtil.isNotBlank(param.getFileName()), UploadFile::getFileName, param.getFileName())
                .like(StringUtil.isNotBlank(param.getUploadUser()), UploadFile::getUploadUser, param.getUploadUser())
                .between(ObjectUtil.isNotEmpty(param.getUploadStartTime()) && ObjectUtil.isNotEmpty(param.getUploadEndTime()), UploadFile::getUploadTime, param.getUploadStartTime(), param.getUploadEndTime())
                .orderByDesc(UploadFile::getUploadTime);
        Page page1 = this.page(page, wrapper);
        for (Object record : page1.getRecords()) {
            UploadFile uploadFile = (UploadFile) record;
            String uploadUser = uploadFile.getUploadUser();
            String nickname = "";
            if (SecurityUtils.getUser() != null){
                nickname = SecurityUtils.getUser().getNickname();
            }
            if (uploadUser.equals(nickname)) {
                uploadFile.setIsDeleted(1);
            }
        }
     return MessageInfo.ok(page1);

    }


}
