package com.vetti.hotake.service.impl;


import cn.hutool.core.util.IdUtil;
import com.vetti.common.config.MinioConfig;
import com.vetti.common.core.service.BaseServiceImpl;
import com.vetti.common.enums.FillTypeEnum;
import com.vetti.common.utils.file.FileTypeUtils;
import com.vetti.common.utils.file.FileUtils;
import com.vetti.common.utils.file.MinioUtil;
import com.vetti.common.utils.sign.Md5Utils;
import com.vetti.hotake.domain.HotakeSysFile;
import com.vetti.hotake.domain.dto.HotakeSysFileDto;
import com.vetti.hotake.domain.vo.HotakeSysFileVo;
import com.vetti.hotake.mapper.HotakeSysFileMapper;
import com.vetti.hotake.service.IHotakeSysFileService;
import org.apache.commons.collections4.CollectionUtils;
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 java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.vetti.common.utils.SecurityUtils.getLoginUser;

/**
 * 文件管理Service业务层处理
 *
 * @author ID
 * @date 2025-09-06
 */
@SuppressWarnings("all")
@Service
public class HotakeSysFileServiceImpl extends BaseServiceImpl implements IHotakeSysFileService {
    @Resource
    private HotakeSysFileMapper hotakeSysFileMapper;

    @Resource
    MinioUtil minioUtil;

    @Resource
    MinioConfig minioConfig;

    /**
     * 查询文件管理
     *
     * @param id 文件管理主键
     * @return 文件管理
     */
    @Transactional(readOnly = true)
    @Override
    public HotakeSysFile selectHotakeSysFileById(Long id) {
        return hotakeSysFileMapper.selectHotakeSysFileById(id);
    }

    /**
     * 查询文件管理列表
     *
     * @param HotakeSysFile 文件管理
     * @return 文件管理
     */
    @Transactional(readOnly = true)
    @Override
    public List<HotakeSysFileDto> selectHotakeSysFileList(HotakeSysFile HotakeSysFile) {
        List<HotakeSysFileDto> l = new ArrayList<>();
        List<HotakeSysFile> dataL = hotakeSysFileMapper.selectHotakeSysFileList(HotakeSysFile);
        if (CollectionUtils.isNotEmpty(dataL)) {
            dataL.forEach(e -> {
                l.add(HotakeSysFileDto.build(url(e), e));
            });
        }
        return l;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public HotakeSysFile uploadFile(MultipartFile file, String minioBucketName) {
        HotakeSysFileVo fileVo = new HotakeSysFileVo();
        fileVo.setMinioBucketName(minioBucketName);
        return insertHotakeSysFile(file, fileVo);
    }

    /**
     * 新增文件管理
     *
     * @param HotakeSysFile 文件管理
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public HotakeSysFile insertHotakeSysFile(MultipartFile file, HotakeSysFileVo fileVo) {
        if (file == null) {
            throw new IllegalArgumentException("文件不能为空");
        }
        if (StringUtils.isEmpty(fileVo.getMinioBucketName())) {
            throw new IllegalArgumentException("桶不能为空");
        }
        HotakeSysFile sysFile = new HotakeSysFile();
        sysFile.setUploadPlatform(1);//PC
        sysFile.setMinioBucketName(fileVo.getMinioBucketName());
        sysFile.setCode(IdUtil.fastSimpleUUID());
        updateData(file, sysFile);
        fill(FillTypeEnum.INSERT.getCode(), sysFile);
        hotakeSysFileMapper.insertHotakeSysFile(sysFile);
        return sysFile;
    }

    private boolean checkCode(HotakeSysFile HotakeSysFile) {
        HotakeSysFile query = new HotakeSysFile();
        query.setCode(HotakeSysFile.getCode());
        query.setMinioBucketName(HotakeSysFile.getMinioBucketName());
        List<HotakeSysFile> HotakeSysFiles = hotakeSysFileMapper.selectHotakeSysFileList(HotakeSysFile);
        if (HotakeSysFiles.isEmpty()) {
            return false;
        }
        return true;
    }

    @Override
    public void updateData(MultipartFile file, HotakeSysFile HotakeSysFile) {
        try {
            String fileUrl = minioUtil.uploadFile(file, minioUtil.objectName(getLoginUser().getUserId()), HotakeSysFile.getMinioBucketName());
            HotakeSysFile.setStoragePath(fileUrl);
            HotakeSysFile.setAvailable(1);//可用
//            HotakeSysFile.setUploadPlatform(1);//PC
            HotakeSysFile.setFileName(FileUtils.cleanFileName(file.getOriginalFilename()));
            HotakeSysFile.setFileType(FileTypeUtils.getFileType(file.getOriginalFilename()));
            HotakeSysFile.setFileSize(file.getSize());
            //根据字节大小计算文件大小
            HotakeSysFile.setFileSizeShow(calculateSize(file.getSize()));
            HotakeSysFile.setFileMd5(Md5Utils.getFileMd5(FileUtils.convert(file)));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 修改文件管理
     *
     * @param HotakeSysFile 文件管理
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateHotakeSysFile(MultipartFile file, HotakeSysFile HotakeSysFile) {
        HotakeSysFile old = hotakeSysFileMapper.selectHotakeSysFileById(HotakeSysFile.getId());
        if (file == null) {
            old.setRemark(HotakeSysFile.getRemark());
            fill(FillTypeEnum.UPDATE.getCode(), old);
            return hotakeSysFileMapper.updateHotakeSysFile(old);
        }
        HotakeSysFile.setUploadPlatform(1);//PC
        updateData(file, HotakeSysFile);
        fill(FillTypeEnum.UPDATE.getCode(), HotakeSysFile);
        return hotakeSysFileMapper.updateHotakeSysFile(HotakeSysFile);
    }

    /**
     * 批量删除文件管理
     *
     * @param ids 需要删除的文件管理主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteHotakeSysFileByIds(Long[] ids) {
        return hotakeSysFileMapper.deleteHotakeSysFileByIds(ids);
    }

    /**
     * 删除文件管理信息
     *
     * @param id 文件管理主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteHotakeSysFileById(Long id) {
        return hotakeSysFileMapper.deleteHotakeSysFileById(id);
    }

    /**
     * 批量新增文件管理
     *
     * @param HotakeSysFileList 文件管理列表
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int batchInsertHotakeSysFile(List<HotakeSysFile> HotakeSysFileList) {
        return hotakeSysFileMapper.batchInsertHotakeSysFile(HotakeSysFileList);
    }

    @Override
    public int availableSysFile(Long id) {
        HotakeSysFile HotakeSysFile = hotakeSysFileMapper.selectHotakeSysFileById(id);
        HotakeSysFile.setAvailable(2);
        fill(FillTypeEnum.UPDATE.getCode(), HotakeSysFile);
        return hotakeSysFileMapper.updateHotakeSysFile(HotakeSysFile);
    }

    @Override
    public String url(HotakeSysFile data) {
        return minioConfig.getEndpoint() + "/" + data.getMinioBucketName() + "/" + data.getStoragePath();
    }

    @Override
    public String url(Long id) {
        return url(hotakeSysFileMapper.selectHotakeSysFileById(id));
    }

    @Override
    public Map<Long, String> url(Long[] ids) {
        List<HotakeSysFile> l = hotakeSysFileMapper.selectHotakeSysFileByIds(ids);
        if (CollectionUtils.isEmpty(l)) {
            return null;
        }
        Map<Long, String> map = new HashMap<>();
        l.forEach(e -> {
            map.put(e.getId(), url(e));
        });
        return map;
    }

    /**
     * 计算文件夹或文件大小
     * 单位：B, KB, M, G, T
     * @param sizes
     * @return
     */
    private String calculateSize(Long sizes){
        if(sizes != null){
            if(new BigDecimal(sizes).compareTo(new BigDecimal(1024)) < 0){
                return sizes+"B";
            }
            if(new BigDecimal(sizes).compareTo(new BigDecimal(1024)) >= 0 &&
                    new BigDecimal(sizes).compareTo(new BigDecimal(1048576)) < 0){
                BigDecimal size = new BigDecimal(sizes).divide(new BigDecimal(1024)).
                        setScale(2,BigDecimal.ROUND_HALF_UP);
                return size+"KB";
            }
            if(new BigDecimal(sizes).compareTo(new BigDecimal(1048576)) >= 0 &&
                    new BigDecimal(sizes).compareTo(new BigDecimal(1073741824)) < 0){
                BigDecimal size = new BigDecimal(sizes).divide(new BigDecimal(1048576)).
                        setScale(2,BigDecimal.ROUND_HALF_UP);
                return size+"M";
            }
            if(new BigDecimal(sizes).compareTo(new BigDecimal(1073741824)) >= 0 &&
                    new BigDecimal(sizes).compareTo(new BigDecimal(1099511627776L)) < 0){
                BigDecimal size = new BigDecimal(sizes).divide(new BigDecimal(1073741824)).
                        setScale(2,BigDecimal.ROUND_HALF_UP);
                return size+"G";
            }
            if(new BigDecimal(sizes).compareTo(new BigDecimal(1099511627776L)) >= 0){
                BigDecimal size = new BigDecimal(sizes).divide(new BigDecimal(1099511627776L)).
                        setScale(2,BigDecimal.ROUND_HALF_UP);
                return size+"T";
            }
        }else{
            return "0B";
        }
        return "0B";
    }


}
