package com.ruoyi.platform.service.impl;

import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.platform.annotations.CheckDuplicate;
import com.ruoyi.platform.domain.Dataset;
import com.ruoyi.platform.domain.DatasetVersion;
import com.ruoyi.platform.mapper.DatasetDao;
import com.ruoyi.platform.mapper.DatasetVersionDao;
import com.ruoyi.platform.service.DatasetVersionService;
import com.ruoyi.platform.service.MinioService;
import com.ruoyi.platform.utils.FileUtil;
import com.ruoyi.platform.utils.HttpUtils;
import com.ruoyi.platform.vo.LabelDatasetVersionVo;
import com.ruoyi.system.api.model.LoginUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * (DatasetVersion)表服务实现类
 *
 * @author Xidaray
 * @since 2024-01-03 16:57:12
 */
@Service("datasetVersionService")
public class DatasetVersionServiceImpl implements DatasetVersionService {
    @Resource
    private DatasetVersionDao datasetVersionDao;
    @Resource
    private DatasetDao datasetDao;
    // 固定存储桶名
    @Value("${minio.dataReleaseBucketName}")
    private String bucketName;
    @Resource
    private MinioService minioService;
    // 固定存储桶名
    @Value("${labelStudio.loaclUrl}")
    private String labelloaclUrl;
    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public DatasetVersion queryById(Integer id) {
        return this.datasetVersionDao.queryById(id);
    }

    /**
     * 分页查询
     *
     * @param datasetVersion 筛选条件
     * @param pageRequest      分页对象
     * @return 查询结果
     */
    @Override
    public Page<DatasetVersion> queryByPage(DatasetVersion datasetVersion, PageRequest pageRequest) {
        long total = this.datasetVersionDao.count(datasetVersion);
        return new PageImpl<>(this.datasetVersionDao.queryAllByLimit(datasetVersion, pageRequest), pageRequest, total);
    }

    /**
     * 新增数据
     *
     * @param datasetVersion 实例对象
     * @return 实例对象
     */
    @Override
    public DatasetVersion insert(DatasetVersion datasetVersion) throws Exception {
        //插入预备
        LoginUser loginUser = SecurityUtils.getLoginUser();
        datasetVersion.setCreateBy(loginUser.getUsername());
        datasetVersion.setUpdateBy(loginUser.getUsername());
        datasetVersion.setUpdateTime(new Date());
        datasetVersion.setCreateTime(new Date());
        datasetVersion.setState(1);
        this.datasetVersionDao.insert(datasetVersion);
        return datasetVersion;
    }

    /**
     * 修改数据
     *
     * @param datasetVersion 实例对象
     * @return 实例对象
     */
    @Override
    public DatasetVersion update(DatasetVersion datasetVersion) {
        int currentState = datasetVersion.getState();
        if (currentState == 0){
            throw new RuntimeException("数据集版本已被删除，无法更新");
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        datasetVersion.setUpdateBy(loginUser.getUsername());
        datasetVersion.setUpdateTime(new Date());
        this.datasetVersionDao.update(datasetVersion);
        //插入时需要更新对应的数据集更新时间
        Integer datasetId = datasetVersion.getDatasetId();
        Dataset dataset = this.datasetDao.queryById(datasetId);
        dataset.setUpdateTime(new Date());
        this.datasetDao.update(dataset);
        return this.queryById(datasetVersion.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.datasetVersionDao.deleteById(id) > 0;
    }


    @Override
    public String removeById(Integer id) throws Exception {
        DatasetVersion datasetVersion = this.datasetVersionDao.queryById(id);
        if (datasetVersion == null){
            throw new Exception("数据集版本信息不存在");
        }
        //判断权限，只有admin和创建者本身可以删除该数据集版本信息
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String username = loginUser.getUsername();
        String createdBy = datasetVersion.getCreateBy();
        if (!(StringUtils.equals(username,"admin") || StringUtils.equals(username,createdBy))){
            throw new Exception("无权限删除该数据集版本");
        }

        datasetVersion.setState(0);
        return this.datasetVersionDao.update(datasetVersion)>0?"删除数据集版本成功":"删除数据集版本失败";
    }

    @Override
    public List<DatasetVersion> queryByDatasetId(Integer datasetId) {
        return datasetVersionDao.queryByDatasetId(datasetId);
    }

    @Override
    public DatasetVersion queryByDatasetVersion(DatasetVersion datasetVersion) {
        return datasetVersionDao.queryByDatasetVersion(datasetVersion);
    }

    @Override
    public Map<String,Object> queryByDatasetIdAndVersion(Integer datasetId, String version) {
        Map<String, Object> response = new HashMap<>();

        List<DatasetVersion> datasetVersionList = this.datasetVersionDao.queryAllByDatasetVersion(datasetId, version);
        datasetVersionList.stream()
                .filter(datasetVersion -> datasetVersion.getUrl() != null && !datasetVersion.getUrl().isEmpty())
                .findFirst()
                .ifPresent(datasetVersion -> {
                    String url = datasetVersion.getUrl();
                    response.put("path", url);
//                    String path = bucketName + '/' + url.substring(0, url.lastIndexOf('/'));
//                    response.put("path", path);
                });

        response.put("content", datasetVersionList);
        return response;
    }

    @Override
    public Map<Integer, String> deleteDatasetVersion(Integer datasetId, String version) throws Exception {
        Map<Integer, String> results = new HashMap<Integer,String>();
        // 根据模型ID和版本查询所有模型版本
        List<DatasetVersion> versions = this.datasetVersionDao.queryAllByDatasetVersion(datasetId, version);
        //逻辑删除列表中的数据项
        for(DatasetVersion datasetVersion:versions){
            String result = this.removeById(datasetVersion.getId());
            results.put(datasetVersion.getId(), result);
        }
        return results;
    }

    @Override
    public void checkDeclaredVersion(DatasetVersion insert) throws Exception {
        DatasetVersion datasetVersion = datasetVersionDao.queryByDatasetVersion(insert);
        if (datasetVersion != null) {
            Field[] fields = DatasetVersion.class.getDeclaredFields();
            for (Field field : fields) {
                if (field.isAnnotationPresent(CheckDuplicate.class)) {
                    CheckDuplicate annotation = field.getAnnotation(CheckDuplicate.class);
                    throw new Exception(field.getName() + annotation.message());
                }
            }
        }
    }

    @Override
    public String addDatasetVersions(List<DatasetVersion> datasetVersions) throws Exception {
        try {
            // 遍历传入的 datasetVersions 列表
            for(DatasetVersion datasetVersion : datasetVersions) {
                insertPrepare(datasetVersion);
            }
            this.datasetVersionDao.insertBatch(datasetVersions);
            return "新增数据集版本成功";
        } catch (Exception e) {
            // 如果出现异常，返回异常消息
            throw new Exception("新增数据集版本失败: " + e.getMessage());

        }
    }

//    @Override
//    public void addDatasetVersionsFromLabel(LabelDatasetVersionVo labelDatasetVersionVo) throws Exception{
//        Dataset dataset = datasetDao.queryById(labelDatasetVersionVo.getDataset_id());
//        if (dataset == null){
//            throw new Exception("数据集不存在");
//        }
//        // 获取label-studio数据流
//        Map<String, String> headers = new HashMap<String, String>();
//        headers.put("Authorization","Token "+labelDatasetVersionVo.getToken());
//        InputStream inputStream = HttpUtils.getIntputStream(labelloaclUrl+"/api/projects/"+labelDatasetVersionVo.getProject_id()+"/export?exportType="+labelDatasetVersionVo.getExportType(), headers);
//        // 构建objectName
//        String username = SecurityUtils.getLoginUser().getUsername();
//        String url = username + "/" + DateUtils.dateTimeNow() + "/" + dataset.getName()+"_"+labelDatasetVersionVo.getVersion()+"."+labelDatasetVersionVo.getExportType();
//        String objectName = "datasets/" + url;
//        String formattedSize = FileUtil.formatFileSize(inputStream.available());
//        minioService.uploaInputStream(bucketName,objectName,inputStream);
//        //保存DatasetVersion
//        DatasetVersion datasetVersion = new DatasetVersion();
//        datasetVersion.setVersion(labelDatasetVersionVo.getVersion());
//        datasetVersion.setDatasetId(labelDatasetVersionVo.getDataset_id());
//        datasetVersion.setFileName(dataset.getName()+"_"+labelDatasetVersionVo.getVersion()+"."+labelDatasetVersionVo.getExportType());
//
//        datasetVersion.setFileSize(formattedSize);
//        datasetVersion.setUrl(objectName);
//        datasetVersion.setDescription(labelDatasetVersionVo.getDesc());
//        this.insert(datasetVersion);
//    }

    private void insertPrepare(DatasetVersion datasetVersion) throws Exception {
        checkDeclaredVersion(datasetVersion);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        datasetVersion.setCreateBy(loginUser.getUsername());
        datasetVersion.setUpdateBy(loginUser.getUsername());
        datasetVersion.setUpdateTime(new Date());
        datasetVersion.setCreateTime(new Date());
        datasetVersion.setState(1);
        //插入时需要更新对应的数据集更新时间
        Integer datasetId = datasetVersion.getDatasetId();
        Dataset dataset = this.datasetDao.queryById(datasetId);
        dataset.setUpdateTime(new Date());
        this.datasetDao.update(dataset);
    }
}
