package com.yida.data.system.service.impl;

import cc.mrbird.febs.common.redis.service.RedisService;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yida.data.common.core.entity.ReceiveMsg;
import com.yida.data.common.core.entity.constant.CachePrefixConstant;
import com.yida.data.common.core.entity.system.EduSysFile;
import com.yida.data.common.core.utils.FileUtil;
import com.yida.data.system.mapper.EduSysFileMapper;
import com.yida.data.system.repository.ReceiveMsgRepository;
import com.yida.data.system.service.CommonService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

@Service
@RefreshScope
@Slf4j
@RequiredArgsConstructor
public class CommonServiceImpl implements CommonService {

    private final EduSysFileMapper eduSysFileMapper;
    private final ReceiveMsgRepository receiveMsgRepository;
    private final RedisService redisService;

    @Value("${febs.uploadUrl}")
    private String uploadUrl;

    // 单次保存最大数量
    private final static Long SAVE_RECEIVE_MAX_SIZE = 1000L;

    @Override
    public EduSysFile upload(MultipartFile file) {
        EduSysFile sysFile = new EduSysFile();
        // 上传到本地
        String path = FileUtil.uploadMultipartFile(file);
        File localFile = new File(path);
        // md5校验文件是否存在
        String md5 = SecureUtil.md5(localFile);
        EduSysFile exist = eduSysFileMapper
            .selectOne(Wrappers.lambdaQuery(new EduSysFile()).eq(EduSysFile::getMd5, md5));
        if (exist != null) {
            localFile.delete();
            return exist;
        }
        // 文件数据入库
        sysFile.setOriginName(file.getOriginalFilename());
        sysFile.setFileSize(localFile.length());
        sysFile.setMd5(md5);
        // 上传到媒资
        String url = FileUtil.uploadFileToMediaServer(uploadUrl, path);
        // 视频文件保存封面
        if (FileUtil.isVideo(cn.hutool.core.io.FileUtil.getSuffix(sysFile.getOriginName()))) {
            sysFile.setCoverUrl(url.split(",")[1]);
        }
        sysFile.setUrl(url.split(",")[0]);
        eduSysFileMapper.insert(sysFile);
        localFile.delete();
        return sysFile;
    }

    @Override
    public String uploadImg(String code) {
        String path = FileUtil.uploadBase64Img(code, "png");
        File file = new File(path);
        if (file.length() > 10 * 1024 * 1024) {
            // 循环压缩到1000kb以下
            try {
                while ((new File(path).length() / 1024 / 1024) > 10) {
                    Thumbnails.of(path).scale(0.5).toFile(path);
                }
            } catch (Exception e) {
                log.error("压缩失败,msg:[{}],stack:[{}]", e.getMessage(), e.getStackTrace());
            }
        }
        File localFile = new File(path);
        // md5校验文件是否存在
        String md5 = SecureUtil.md5(localFile);
        EduSysFile exist = eduSysFileMapper
            .selectOne(Wrappers.lambdaQuery(new EduSysFile()).eq(EduSysFile::getMd5, md5));
        if (exist != null) {
            localFile.delete();
            return exist.getUrl();
        }
        EduSysFile sysFile = new EduSysFile();
        // 文件数据入库
        sysFile.setOriginName(StrUtil.uuid().replace("-", "") + ".png");
        sysFile.setFileSize(localFile.length());
        sysFile.setMd5(md5);
        // 上传到媒资
        String url = FileUtil.uploadFileToMediaServer(uploadUrl, path);
        sysFile.setUrl(url.split(",")[0]);
        eduSysFileMapper.insert(sysFile);
        localFile.delete();
        return url;
    }

    @Override
    public void saveReceiveMsg() {
        Long size = redisService.lGetListSize(CachePrefixConstant.RECEIVE_MSG);
        if (size > 0) {
            // 保存的数量
            long saveSize = Math.min(size, SAVE_RECEIVE_MAX_SIZE);
            List<ReceiveMsg> saveData = new ArrayList<>();
            // 保存后删除数据
            for (int i = 0; i < saveSize; i++) {
                ReceiveMsg msg = (ReceiveMsg) redisService.lLeftPop(CachePrefixConstant.RECEIVE_MSG);
                if (msg != null) {
                    saveData.add(msg);
                }
            }
            receiveMsgRepository.saveAll(saveData);
            log.info("保存{}条接收数据", saveSize);
        }
    }
}
