package com.backendsys.modules.upload.service.impl;

import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.backendsys.exception.CustException;
import com.backendsys.modules.common.config.security.utils.HttpRequestUtil;
import com.backendsys.modules.sdk.tencentcloud.cos.service.TencentCosService;
import com.backendsys.modules.upload.dao.SysFileDao;
import com.backendsys.modules.upload.entity.SysFile;
import com.backendsys.modules.upload.service.SysFileMultipartService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qcloud.cos.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

@Service
public class SysFileMultipartServiceImpl implements SysFileMultipartService {

    @Autowired
    private HttpRequestUtil httpRequestUtil;
    @Autowired
    private TencentCosService tencentCosService;
    @Autowired
    private SysFileDao sysFileDao;

    // 初始化分块上传 (获得 upload_id, object_key)
    @Override
    public Map<String, Object> initiateMultipartUpload(MultipartFile multipartFile, Long category_id, Integer target) {

        String upload_id = null;
        String object_key = null;

        // target: 上传目标 (-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云)
        if (target == 1) {
            InitiateMultipartUploadResult uploadResult = tencentCosService.initiateMultipartUpload(multipartFile);
            upload_id = uploadResult.getUploadId();
            object_key = uploadResult.getKey();
        }

        if (StrUtil.isEmpty(upload_id) || StrUtil.isEmpty(object_key)) {
            throw new CustException("upload_id 或 object_key 不能为空");
        }

        try {
            // 根据文件MD5 判断是否上传过文件 (如果上传过，则仅更新记录，不再上传文件)
            String md5 = DigestUtil.md5Hex(multipartFile.getInputStream());
            SysFile sysFileEntity = sysFileDao.selectOne(new LambdaQueryWrapper<SysFile>().eq(SysFile::getMd5, md5));
            if (sysFileEntity == null) {
                sysFileEntity = new SysFile();
                sysFileEntity.setCategory_id(category_id);
                sysFileEntity.setUser_id(httpRequestUtil.getUserId());
                sysFileEntity.setUpload_id(upload_id);
                sysFileEntity.setName(FileNameUtil.getName(object_key));
                sysFileEntity.setMd5(md5);
                sysFileEntity.setObject_key(object_key);
                sysFileDao.insert(sysFileEntity);
            } else {
                // [更新] 上传文件记录
                sysFileEntity.setCategory_id(category_id);
                sysFileEntity.setUpload_id(upload_id);
                sysFileEntity.setName(FileNameUtil.getName(object_key));
                sysFileEntity.setObject_key(object_key);
                sysFileDao.updateById(sysFileEntity);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        Map<String, Object> resp = new LinkedHashMap<>();
        resp.put("upload_id", upload_id);
        resp.put("object_key", object_key);
        return resp;
    }

    // 上传分块
    @Override
    public Map<String, Object> uploadMultipart(MultipartFile multipartFile, String upload_id) {

        if (StrUtil.isEmpty(upload_id)) throw new CustException("upload_id 不能为空");

        SysFile sysFileEntity = sysFileDao.selectOne(new LambdaQueryWrapper<SysFile>().eq(SysFile::getUpload_id, upload_id));
        if (sysFileEntity == null) throw new CustException("upload_id 不存在");

        String object_key = sysFileEntity.getObject_key();

        // 查询分块上传情况 (获得下次要上传的位置)
        PartListing partListing = listParts(upload_id, object_key);
        Integer partNumberMarker = partListing.getPartNumberMarker() + 1;

        UploadPartResult partResult = tencentCosService.uploadPart(multipartFile, upload_id, object_key, partNumberMarker);
        System.out.println("partResult:");
        System.out.println(partResult);

        Map<String, Object> resp = new LinkedHashMap<>();
        resp.put("upload_id", upload_id);
        resp.put("object_key", object_key);
        resp.put("part_number", partNumberMarker);
        resp.put("part_etag", partResult.getPartETag());
        return resp;
    }

    // 查询分块上传情况
    @Override
    public PartListing listParts(String upload_id, String object_key) {
        return tencentCosService.listParts(upload_id, object_key);
    }

    // 完成分块上传
    @Override
    public Map<String, Object> completeMultipartUpload(String upload_id) {

        if (StrUtil.isEmpty(upload_id)) throw new CustException("upload_id 不能为空");

        SysFile sysFileEntity = sysFileDao.selectOne(new LambdaQueryWrapper<SysFile>().eq(SysFile::getUpload_id, upload_id));
        if (sysFileEntity == null) throw new CustException("upload_id 不存在");

        String object_key = sysFileEntity.getObject_key();

//        // 查询分块上传情况 (获得下次要上传的位置)
//        PartListing partListing = listParts(upload_id, object_key);
//        List<PartSummary> partSummaryList = partListing.getParts();
//
//        List<PartETag> partETags = new ArrayList<>();
//
//        tencentCosService.completeMultipartUpload(upload_id, object_key, partETags);

        return Map.of("upload_id", upload_id);
    }

}
