package com.trade.service.filestorage.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.trade.common.utils.LoggerUtil;
import com.trade.common.validate.ValidatorGroup;
import com.trade.common.validate.ValidatorUtil;
import com.trade.service.filestorage.dto.FileAbstractDto;
import com.trade.service.filestorage.entity.TFileStorage;
import com.trade.service.filestorage.mapper.BusinessRelateFileMapper;
import com.trade.service.filestorage.entity.BusinessRelateFile;
import com.trade.service.filestorage.service.BusinessRelateFileBaseService;
import com.trade.service.filestorage.service.TFileStorageService;
import org.slf4j.Logger;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 文件关联关系基础服务实现类
 *
 * @author hlb
 * @since 2024-05-29 15:07:42
 */
@Service("businessRelateFileBaseService")
public class BusinessRelateFileBaseServiceImpl extends ServiceImpl<BusinessRelateFileMapper, BusinessRelateFile> implements BusinessRelateFileBaseService {

    private static final Logger log = LoggerUtil.logger(LoggerUtil.LogFileNameEnum.SERVICES_LOG);
    @Resource
    private TFileStorageService FileStorageService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addBusinessRelateFiles(List<BusinessRelateFile> businessRelateFiles) {
        if (CollUtil.isEmpty(businessRelateFiles)) {
            return;
        }
        for (BusinessRelateFile businessRelateFile : businessRelateFiles) {
            ValidatorUtil.validator(ValidatorGroup.ValidatorType.ADD, businessRelateFile);
        }
        this.saveBatch(businessRelateFiles);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void upsertBusinessRelateFiles(BusinessRelateFile businessRelateFile) {
        BusinessRelateFile one = this.lambdaQuery()
                .eq(BusinessRelateFile::getBelongId, businessRelateFile.getBelongId())
                .eq(BusinessRelateFile::getBelongType, businessRelateFile.getBelongType())
                .eq(BusinessRelateFile::getFileType, businessRelateFile.getFileType())
                .orderByDesc(BusinessRelateFile::getGmtModified).last("limit 1").one();
        if (one != null) {
            businessRelateFile.setId(one.getId());
        }
        this.saveOrUpdate(businessRelateFile);
    }

    @Override
    public void fillBizObjFiles(@NonNull Object bizObj, @NonNull Long belongId, String belongType, String fileType) {
        List<BusinessRelateFile> relateFiles = this.lambdaQuery().eq(BusinessRelateFile::getBelongId, belongId)
                .eq(BusinessRelateFile::getBelongType, belongType)
                .eq(StrUtil.isNotBlank(fileType), BusinessRelateFile::getFileType, fileType).list().stream().distinct()
                .collect(Collectors.toList());
        if (CollUtil.isEmpty(relateFiles)) {
            return;
        }
        for (BusinessRelateFile relateFile : relateFiles) {
            if (!ReflectUtil.hasField(bizObj.getClass(), relateFile.getFileType())) {
                continue;
            }
            TFileStorage fileStorage = FileStorageService.getFileStorageById(relateFile.getFileId());
            ReflectUtil.setFieldValue(bizObj, relateFile.getFileType(), new FileAbstractDto(fileStorage));
        }
    }

    @Override
    public List<BusinessRelateFile> getBizObjFiles(Long belongId, String belongType, String fileType) {
        return this.lambdaQuery().eq(BusinessRelateFile::getBelongId, belongId)
                .eq(BusinessRelateFile::getBelongType, belongType)
                .eq(StrUtil.isNotBlank(fileType), BusinessRelateFile::getFileType, fileType).list().stream().distinct()
                .collect(Collectors.toList());
    }

    @Override
    public BusinessRelateFile getByCondition(Long belongId, String belongType, String fileType) {
        return this.baseMapper.selectByCondition(belongId, belongType, fileType);
    }
}
