package org.dromara.system.service.impl;


import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import jakarta.annotation.Resource;
import org.dromara.common.core.constant.BizConst;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.QiNiuUtil;
import org.dromara.common.core.utils.file.FileUtil;
import org.dromara.system.domain.SysOss;
import org.dromara.system.domain.vo.SysDictDataVo;
import org.dromara.system.mapper.SysOssMapper;
import org.dromara.system.service.IQiNiuContentService;
import org.dromara.system.service.ISysDictDataService;
import org.jetbrains.annotations.Nullable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 文件上传 服务实现类
 * </p>
 *
 * @author tanSir
 * @since 2021-04-16
 */
@Service
public class QiNiuContentServiceImpl extends ServiceImpl<SysOssMapper, SysOss> implements IQiNiuContentService {
    @Resource
    private ISysDictDataService sysDictItemService;

    @Resource
    private SysOssMapper qiNiuContentMapper;

    @Resource
    private RedisTemplate redisTemplate;


    /**
     * 文件上传, 自定义路径前缀
     *
     * @return
     */
    @Override
    public SysOss upload(MultipartFile file) {
        String prefix = "upload/" + DateUtil.format(LocalDateTimeUtil.now(), DatePattern.PURE_DATE_PATTERN) + "/";
        JSONObject qiNiuConfig = getDynamicQiNiuConfig();
        FileUtil.checkSize(qiNiuConfig.getInteger(BizConst.QNY_MAX_SIZE), file.getSize());
        // 构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(QiNiuUtil.getRegion(qiNiuConfig.getString(BizConst.QNY_ZONE)));
        UploadManager uploadManager = new UploadManager(cfg);
        Auth auth = Auth.create(qiNiuConfig.getString(BizConst.QNY_ACCESS_KEY), qiNiuConfig.getString(BizConst.QNY_SECRET_KEY));
        String upToken = auth.uploadToken(qiNiuConfig.getString(BizConst.QNY_BUCKET_NAME));
        try {
            Long nextId = IdWorker.getId();
            String name = getPrefix(prefix) + nextId + "." + FileUtil.extName(file.getOriginalFilename());
            Response response = uploadManager.put(file.getBytes(), name, upToken);
            // 解析上传成功的结果
            DefaultPutRet putRet = JSON.parseObject(response.bodyString(), DefaultPutRet.class);
            // 存入数据库
            SysOss qiniuContent = new SysOss();
            qiniuContent.setFileName(name);
            qiniuContent.setFileSuffix(FileUtil.getExtensionName(putRet.key));
//            qiniuContent.setBucket(qiNiuConfig.getString(BizConst.QNY_BUCKET_NAME));
            qiniuContent.setOriginalName(FileUtil.getFileNameNoEx(file.getOriginalFilename()));
            qiniuContent.setUrl(qiNiuConfig.getString(BizConst.QNY_STATIC_DOMAIN) + putRet.key);
//            qiniuContent.setFileSize(FileUtil.getSize(file.getSize()));
            qiniuContent.setUpdateTime(DateUtil.date());
            qiniuContent.setOssId(nextId);
            qiNiuContentMapper.insert(qiniuContent);
            return qiniuContent;
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }


    private String getPrefix(String prefix) {
        if (StrUtil.isBlank(prefix)) {
            prefix = "";
        } else {
            String separator = "/";
            if (!prefix.endsWith(separator)) {
                prefix += separator;
            }
            if (prefix.startsWith(separator)) {
                prefix = prefix.substring(1);
            }
        }
        return prefix;
    }


    @Nullable
    private JSONObject getDynamicQiNiuConfig() {
        Object qnyConfig = redisTemplate.opsForValue().get(BizConst.QNY_CONFIG_CACHE);
        if (ObjUtil.isNull(qnyConfig)) {
            Map<String, SysDictDataVo> dictMap = sysDictItemService.selectMapByType(BizConst.QNY_CONFIG).getData();
            if (MapUtil.isEmpty(dictMap)) {
                throw new ServiceException("oss配置不存在！");
            }
            JSONObject jsonObject = new JSONObject();
            dictMap.forEach((k,v)->{
                jsonObject.put(v.getDictLabel(),v.getDictValue());
            });
            redisTemplate.opsForValue().set(BizConst.QNY_CONFIG_CACHE, JSON.toJSONString(jsonObject));
            redisTemplate.expire(BizConst.QNY_CONFIG_CACHE, 30, TimeUnit.MINUTES);
            return jsonObject;
        }

        return JSONObject.parseObject(String.valueOf(qnyConfig));
    }
}
