package com.ai.da.service.impl;

import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.context.UserContext;
import com.ai.da.common.enums.CollectionLevel1TypeEnum;
import com.ai.da.common.enums.CollectionLevel2TypeEnum;
import com.ai.da.common.enums.LibraryLevel1TypeEnum;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.response.ResultEnum;
import com.ai.da.common.utils.*;
import com.ai.da.mapper.primary.*;
import com.ai.da.mapper.primary.entity.*;
import com.ai.da.mapper.secondary.AttributeRetrievalMapper;
import com.ai.da.mapper.secondary.entity.AttributeRetrieval;
import com.ai.da.model.dto.ProjectDTO;
import com.ai.da.model.dto.WorkspaceDTO;
import com.ai.da.model.dto.WorkspaceSaveDTO;
import com.ai.da.model.enums.*;
import com.ai.da.model.vo.*;
import com.ai.da.service.SysFileService;
import com.ai.da.service.WorkspaceService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.netty.util.internal.StringUtil;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.ai.da.common.utils.RedisUtil.UNNAMED_PROJECT_SEQ;


/**
 * 服务实现类
 *
 * @author SHAHAIBO
 * @since 2023-08-01
 */
@Service
public class WorkspaceServiceImpl extends ServiceImpl<WorkspaceMapper, Workspace> implements WorkspaceService {

    @Resource
    private WorkspaceMapper workspaceMapper;

    @Resource
    private ProjectMapper projectMapper;

    @Resource
    private StyleMapper styleMapper;

    @Resource
    private WorkspaceRelStyleMapper workspaceRelStyleMapper;

    @Resource
    private LibraryMapper libraryMapper;
    @Resource
    private BrandDNAMapper brandDNAMapper;

    @Resource
    private SysFileMapper sysFileMapper;

    @Resource
    private SysFileExtraMapper sysFileExtraMapper;

    @Resource
    private MinioUtil minioUtil;

    @Value("${minio.bucketName.sysImage}")
    private String sysImage;

    @Value("${minio.bucketName.users}")
    private String users;

    @Resource
    private SysFileService sysFileService;
    @Resource
    private WorkspaceService workspaceService;

    @Resource
    private CollectionElementMapper collectionElementMapper;
    @Resource
    private CollectionElementRelModelMapper collectionElementRelModelMapper;
    @Resource
    private RedisUtil redisUtil;

    @Override
    public IPage<WorkspaceVO> selectWorkspacePage(IPage<WorkspaceVO> page, WorkspaceVO workspace) {
        return page.setRecords(baseMapper.selectWorkspacePage(page, workspace));
    }

    private final static String WORKSPACE_NAME = "Default workspace name";
    private final static Integer SYSTEM_DESIGNER_PERCENTAGE = 30;

    @Override
    public boolean saveOrUpdate(WorkspaceSaveDTO workspaceDTO) {
        Workspace workspace = CopyUtil.copyObject(workspaceDTO, Workspace.class);
        // 防止前端传值修改标识
        workspace.setIsLastIndex(null);
        AuthPrincipalVo userInfo = UserContext.getUserHolder();
        workspace.setAccountId(userInfo.getId());
        checkWorkspaceName(workspace.getId(), workspace.getWorkSpaceName(), userInfo.getId());
        if (null == workspace.getId()) {
            workspace.setIsLastIndex(0);
            QueryWrapper<SysFile> systemFemaleQw = new QueryWrapper<>();
            systemFemaleQw.lambda().eq(SysFile::getLevel1Type, "Models");
            systemFemaleQw.lambda().eq(SysFile::getLevel2Type, "Female");
            List<SysFile> sysFemaleFiles = sysFileMapper.selectList(systemFemaleQw);
            if (!CollectionUtils.isEmpty(sysFemaleFiles)) {
                workspace.setMannequinFemaleId(sysFemaleFiles.get(0).getId());
                workspace.setMannequinFemaleType(MannequinType.SYSTEM.getValue());
            }
            QueryWrapper<SysFile> systemMaleQw = new QueryWrapper<>();
            systemMaleQw.lambda().eq(SysFile::getLevel1Type, "Models");
            systemMaleQw.lambda().eq(SysFile::getLevel2Type, "Male");
            List<SysFile> sysMaleFiles = sysFileMapper.selectList(systemMaleQw);
            if (!CollectionUtils.isEmpty(sysMaleFiles)) {
                workspace.setMannequinMaleId(sysMaleFiles.get(0).getId());
                workspace.setMannequinMaleType(MannequinType.SYSTEM.getValue());
            }
            workspace.setSex(Sex.FEMALE.getValue());
            workspace.setPosition("Overall");
            workspace.setSystemDesignerPercentage(SYSTEM_DESIGNER_PERCENTAGE);
            int insert = workspaceMapper.insert(workspace);
            if (insert <= 0) {
                throw new BusinessException("save.workspace.failed");
            }
            if (workspaceDTO.getStyleId() != null) {
                WorkspaceRelStyle rel = new WorkspaceRelStyle();
                rel.setWorkspaceId(workspace.getId());
                rel.setStyleId(workspaceDTO.getStyleId());
                workspaceRelStyleMapper.insert(rel);
            }
            return true;
        } else {
            int update = workspaceMapper.updateById(workspace);
            if (update <= 0) {
                throw new BusinessException("update.workspace.failed");
            }
            if (workspaceDTO.getStyleId() != null) {
                QueryWrapper<WorkspaceRelStyle> qw = new QueryWrapper<>();
                qw.lambda().eq(WorkspaceRelStyle::getWorkspaceId, workspace.getId());
                List<WorkspaceRelStyle> workspaceRelStyles = workspaceRelStyleMapper.selectList(qw);
                if (CollectionUtils.isEmpty(workspaceRelStyles)) {
                    WorkspaceRelStyle rel = new WorkspaceRelStyle();
                    rel.setWorkspaceId(workspace.getId());
                    rel.setStyleId(workspaceDTO.getStyleId());
                    workspaceRelStyleMapper.insert(rel);
                } else {
                    WorkspaceRelStyle workspaceRelStyle = workspaceRelStyles.get(0);
                    if (!Objects.equals(workspaceRelStyle.getStyleId(), workspaceDTO.getStyleId())) {
                        workspaceRelStyle.setStyleId(workspaceDTO.getStyleId());
                        workspaceRelStyleMapper.updateById(workspaceRelStyle);
                    }
                }
            } else {
                QueryWrapper<WorkspaceRelStyle> qw = new QueryWrapper<>();
                qw.lambda().eq(WorkspaceRelStyle::getWorkspaceId, workspace.getId());
                List<WorkspaceRelStyle> workspaceRelStyles = workspaceRelStyleMapper.selectList(qw);
                if (!CollectionUtils.isEmpty(workspaceRelStyles)) {
                    WorkspaceRelStyle workspaceRelStyle = workspaceRelStyles.get(0);
                    workspaceRelStyleMapper.deleteById(workspaceRelStyle);
                }
            }
            return true;
        }
    }

    private void checkWorkspaceName(Long id, String workSpaceName, Long accountId) {
        QueryWrapper<Workspace> qw = new QueryWrapper<>();
        qw.lambda().ne(null != id, Workspace::getId, id);
        qw.lambda().eq(Workspace::getWorkSpaceName, workSpaceName);
        qw.lambda().eq(Workspace::getAccountId, accountId);
        List<Workspace> workspaces = baseMapper.selectList(qw);
        if (!CollectionUtils.isEmpty(workspaces)) {
            throw new BusinessException("the.workspaceName.already.exists", ResultEnum.PROMPT.getCode());
        }
    }

    @Override
    public WorkspaceVO getPage(WorkspaceDTO query) {
        WorkspaceVO vo = new WorkspaceVO();
        Long accountId = UserContext.getUserHolder().getId();
        QueryWrapper<Workspace> qw = new QueryWrapper<>();
        qw.lambda().eq(Workspace::getAccountId, accountId);
        IPage<Workspace> page = workspaceMapper.selectPage(new Page<>(query.getPage(), query.getSize()), qw);
        if (page.getTotal() == 0L) {
            // 给用户新建默认workspace
            Workspace workspace = new Workspace();
            workspace.setWorkSpaceName(WORKSPACE_NAME);
            workspace.setSex(Sex.FEMALE.getValue());
            workspace.setSystemDesignerPercentage(SYSTEM_DESIGNER_PERCENTAGE);
            workspace.setPosition("Overall");
            workspace.setAccountId(accountId);
            QueryWrapper<SysFile> systemFemaleQw = new QueryWrapper<>();
            systemFemaleQw.lambda().eq(SysFile::getLevel1Type, "Models");
            systemFemaleQw.lambda().eq(SysFile::getLevel2Type, "Female");
            List<SysFile> sysFemaleFiles = sysFileMapper.selectList(systemFemaleQw);
            if (!CollectionUtils.isEmpty(sysFemaleFiles)) {
                workspace.setMannequinFemaleId(sysFemaleFiles.get(0).getId());
                workspace.setMannequinFemaleType(MannequinType.SYSTEM.getValue());
            }
            QueryWrapper<SysFile> systemMaleQw = new QueryWrapper<>();
            systemMaleQw.lambda().eq(SysFile::getLevel1Type, "Models");
            systemMaleQw.lambda().eq(SysFile::getLevel2Type, "Male");
            List<SysFile> sysMaleFiles = sysFileMapper.selectList(systemMaleQw);
            if (!CollectionUtils.isEmpty(sysMaleFiles)) {
                workspace.setMannequinMaleId(sysMaleFiles.get(0).getId());
                workspace.setMannequinMaleType(MannequinType.SYSTEM.getValue());
            }
            workspace.setIsLastIndex(1);
            int insert = workspaceMapper.insert(workspace);
            if (insert <= 0) {
                throw new BusinessException("save.workspace.failed");
            }
            page = workspaceMapper.selectPage(new Page<>(query.getPage(), query.getSize()), qw);
            IPage<WorkspaceVO> convert = page.convert(
                    o -> {
                        WorkspaceVO workspaceVO = CopyUtil.copyObject(o, WorkspaceVO.class);
                        if (o.getMannequinFemaleId() != null) {
                            if (o.getMannequinFemaleType().equals(ModelType.SYSTEM.getValue())) {
                                workspaceVO.setFemalePresignedUrl(minioUtil.getPreSignedUrl(sysFileMapper.selectById(o.getMannequinFemaleId()).getUrl(), 24 * 60));
                            } else if (o.getMannequinFemaleType().equals(ModelType.LIBRARY.getValue())) {
                                workspaceVO.setFemalePresignedUrl(minioUtil.getPreSignedUrl(libraryMapper.selectById(o.getMannequinFemaleId()).getUrl(), 24 * 60));
                            }
                        }
                        if (o.getMannequinMaleId() != null) {
                            if (o.getMannequinMaleType().equals(ModelType.SYSTEM.getValue())) {
                                workspaceVO.setMalePresignedUrl(minioUtil.getPreSignedUrl(sysFileMapper.selectById(o.getMannequinMaleId()).getUrl(), 24 * 60));
                            } else if (o.getMannequinMaleType().equals(ModelType.LIBRARY.getValue())) {
                                workspaceVO.setMalePresignedUrl(minioUtil.getPreSignedUrl(libraryMapper.selectById(o.getMannequinMaleId()).getUrl(), 24 * 60));
                            }
                        }
                        Sex sex = Sex.getSex(workspaceVO.getSex());
                        Position position = Position.getPosition(workspaceVO.getPosition());
                        workspaceVO.setSexEnum(new BizJson(sex.getValue(), sex.name(), BusinessException.getMessageFromResource(sex.name())));
                        workspaceVO.setPositionEnum(new BizJson(position.getValue(), position.name(), BusinessException.getMessageFromResource(position.name())));
                        return workspaceVO;
                    }
            );
            vo.setPage(PageBaseResponse.success(convert));
            vo.setId(workspace.getId());
            return vo;
        }
        IPage<WorkspaceVO> convert = page.convert(
                o -> {
                    WorkspaceVO workspaceVO = CopyUtil.copyObject(o, WorkspaceVO.class);
                    if (o.getMannequinFemaleId() != null) {
                        if (o.getMannequinFemaleType().equals(ModelType.SYSTEM.getValue())) {
                            workspaceVO.setFemalePresignedUrl(minioUtil.getPreSignedUrl(sysFileMapper.selectById(o.getMannequinFemaleId()).getUrl(), 24 * 60));
                        } else if (o.getMannequinFemaleType().equals(ModelType.LIBRARY.getValue())) {
                            workspaceVO.setFemalePresignedUrl(minioUtil.getPreSignedUrl(libraryMapper.selectById(o.getMannequinFemaleId()).getUrl(), 24 * 60));
                        }
                    }
                    if (o.getMannequinMaleId() != null) {
                        if (o.getMannequinMaleType().equals(ModelType.SYSTEM.getValue())) {
                            workspaceVO.setMalePresignedUrl(minioUtil.getPreSignedUrl(sysFileMapper.selectById(o.getMannequinMaleId()).getUrl(), 24 * 60));
                        } else if (o.getMannequinMaleType().equals(ModelType.LIBRARY.getValue())) {
                            workspaceVO.setMalePresignedUrl(minioUtil.getPreSignedUrl(libraryMapper.selectById(o.getMannequinMaleId()).getUrl(), 24 * 60));
                        }
                    }
                    Sex sex = Sex.getSex(workspaceVO.getSex());
                    Position position = Position.getPosition(workspaceVO.getPosition());
                    workspaceVO.setSexEnum(new BizJson(sex.getValue(), sex.name(), BusinessException.getMessageFromResource(sex.name())));
                    workspaceVO.setPositionEnum(new BizJson(position.getValue(), position.name(), BusinessException.getMessageFromResource(position.name())));
                    return workspaceVO;
                }
        );
        vo.setPage(PageBaseResponse.success(convert));
        QueryWrapper<Workspace> qwIsLastIndex = new QueryWrapper<>();
        qwIsLastIndex.lambda().eq(Workspace::getAccountId, accountId);
        qwIsLastIndex.lambda().eq(Workspace::getIsLastIndex, 1);
        qwIsLastIndex.last("limit 1");
        List<Workspace> workspaces = workspaceMapper.selectList(qwIsLastIndex);
        if (CollectionUtils.isEmpty(workspaces)) {
            throw new BusinessException("the.workspace.lastIndex.not.found");
        }
        vo.setId(workspaces.get(0).getId());
        return vo;
    }

    @Override
    public List<BizJson> getEnumValues(String className) {
        Class clazz;
        try {
            clazz = Class.forName(IEnumDisplay.class.getPackage().getName() + "." + className);
        } catch (ClassNotFoundException e) {
            log.error(e.getMessage());
            throw new BusinessException("enumeration.class.not.found");
        }
        return getEnumValues(clazz);
    }

    @Override
    public WorkspaceVO getByIdNew(Long id) {
        AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder();
        Long accountId = UserContext.getUserHolder().getId();
        QueryWrapper<Workspace> qwOld = new QueryWrapper<>();
        qwOld.lambda().eq(Workspace::getAccountId, accountId);
        qwOld.lambda().eq(Workspace::getIsLastIndex, 1);
        Workspace oldIsLastIndex = workspaceMapper.selectOne(qwOld);
        oldIsLastIndex.setIsLastIndex(0);
        workspaceMapper.updateById(oldIsLastIndex);
        Workspace newIsLastIndex = workspaceMapper.selectById(id);
        newIsLastIndex.setIsLastIndex(1);
        workspaceMapper.updateById(newIsLastIndex);
        WorkspaceVO vo = CopyUtil.copyObject(newIsLastIndex, WorkspaceVO.class);
        if (vo.getMannequinFemaleId() != null) {
            if (vo.getMannequinFemaleType().equals(ModelType.SYSTEM.getValue())) {
                vo.setFemalePresignedUrl(minioUtil.getPreSignedUrl(sysFileMapper.selectById(vo.getMannequinFemaleId()).getUrl(), 24 * 60));
            } else if (vo.getMannequinFemaleType().equals(ModelType.LIBRARY.getValue())) {
                vo.setFemalePresignedUrl(minioUtil.getPreSignedUrl(libraryMapper.selectById(vo.getMannequinFemaleId()).getUrl(), 24 * 60));
            }
        }
        if (vo.getMannequinMaleId() != null) {
            if (vo.getMannequinMaleType().equals(ModelType.SYSTEM.getValue())) {
                vo.setMalePresignedUrl(minioUtil.getPreSignedUrl(sysFileMapper.selectById(vo.getMannequinMaleId()).getUrl(), 24 * 60));
            } else if (vo.getMannequinMaleType().equals(ModelType.LIBRARY.getValue())) {
                vo.setMalePresignedUrl(minioUtil.getPreSignedUrl(libraryMapper.selectById(vo.getMannequinMaleId()).getUrl(), 24 * 60));
            }
        }
        Sex sex = Sex.getSex(vo.getSex());
        Position position = Position.getPosition(vo.getPosition());
        vo.setSexEnum(new BizJson(sex.getValue(), sex.name(), BusinessException.getMessageFromResource(sex.name())));
        vo.setPositionEnum(new BizJson(position.getValue(), position.name(), BusinessException.getMessageFromResource(position.name())));
        QueryWrapper<WorkspaceRelStyle> qw = new QueryWrapper<>();
        qw.lambda().eq(WorkspaceRelStyle::getWorkspaceId, vo.getId());
        List<WorkspaceRelStyle> workspaceRelStyles = workspaceRelStyleMapper.selectList(qw);
        if (!CollectionUtils.isEmpty(workspaceRelStyles)) {
            Long styleId = workspaceRelStyles.get(0).getStyleId();
            vo.setStyleId(styleId);
            Style style = styleMapper.selectById(styleId);
            StyleEnum styleEnum = StyleEnum.fromName(style.getName());
            vo.setStyle(styleEnum.name());
            Map<String, List<String>> allKeywordsByStyle = StyleKeywordMapper.getAllKeywordsByStyle(styleEnum);
            vo.setAllKeywordsByStyle(allKeywordsByStyle);
            if (authPrincipalVo.getLanguage().equals(Language.ENGLISH.name())) {
                vo.setStyleName(styleEnum.getEnglish());
            } else {
                vo.setStyleName(styleEnum.getChinese());
            }
        }
        return vo;
    }

    @Override
    public WorkspaceVO getByIdForProject(Long id) {
        AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder();
        Long accountId = UserContext.getUserHolder().getId();
//        QueryWrapper<Workspace> qwOld = new QueryWrapper<>();
//        qwOld.lambda().eq(Workspace::getAccountId, accountId);
//        qwOld.lambda().eq(Workspace::getIsLastIndex, 1);
//        Workspace oldIsLastIndex = workspaceMapper.selectOne(qwOld);
//        oldIsLastIndex.setIsLastIndex(0);
//        workspaceMapper.updateById(oldIsLastIndex);
        Workspace newIsLastIndex = workspaceMapper.selectById(id);
//        newIsLastIndex.setIsLastIndex(1);
//        workspaceMapper.updateById(newIsLastIndex);
        WorkspaceVO vo = CopyUtil.copyObject(newIsLastIndex, WorkspaceVO.class);
        if (vo.getMannequinFemaleId() != null) {
            if (vo.getMannequinFemaleType().equals(ModelType.SYSTEM.getValue())) {
                vo.setFemalePresignedUrl(minioUtil.getPreSignedUrl(sysFileMapper.selectById(vo.getMannequinFemaleId()).getUrl(), 24 * 60));
            } else if (vo.getMannequinFemaleType().equals(ModelType.LIBRARY.getValue())) {
                vo.setFemalePresignedUrl(minioUtil.getPreSignedUrl(libraryMapper.selectById(vo.getMannequinFemaleId()).getUrl(), 24 * 60));
            }
        }
        if (vo.getMannequinMaleId() != null) {
            if (vo.getMannequinMaleType().equals(ModelType.SYSTEM.getValue())) {
                vo.setMalePresignedUrl(minioUtil.getPreSignedUrl(sysFileMapper.selectById(vo.getMannequinMaleId()).getUrl(), 24 * 60));
            } else if (vo.getMannequinMaleType().equals(ModelType.LIBRARY.getValue())) {
                vo.setMalePresignedUrl(minioUtil.getPreSignedUrl(libraryMapper.selectById(vo.getMannequinMaleId()).getUrl(), 24 * 60));
            }
        }
        if (!StringUtils.isEmpty(vo.getSex())) {
            Sex sex = Sex.getSex(vo.getSex());
            vo.setSexEnum(new BizJson(sex.getValue(), sex.name(), BusinessException.getMessageFromResource(sex.name())));

        }
        if (!StringUtils.isEmpty(vo.getPosition())) {
            Position position = Position.getPosition(vo.getPosition());
            vo.setPositionEnum(new BizJson(position.getValue(), position.name(), BusinessException.getMessageFromResource(position.name())));
        }
        QueryWrapper<WorkspaceRelStyle> qw = new QueryWrapper<>();
        qw.lambda().eq(WorkspaceRelStyle::getWorkspaceId, vo.getId());
        List<WorkspaceRelStyle> workspaceRelStyles = workspaceRelStyleMapper.selectList(qw);
        if (!CollectionUtils.isEmpty(workspaceRelStyles)) {
            Long styleId = workspaceRelStyles.get(0).getStyleId();
            vo.setStyleId(styleId);
            Style style = styleMapper.selectById(styleId);
            StyleEnum styleEnum = StyleEnum.fromName(style.getName());
            vo.setStyle(styleEnum.name());
            Map<String, List<String>> allKeywordsByStyle = StyleKeywordMapper.getAllKeywordsByStyle(styleEnum);
            vo.setAllKeywordsByStyle(allKeywordsByStyle);
            if (authPrincipalVo.getLanguage().equals(Language.ENGLISH.name())) {
                vo.setStyleName(styleEnum.getEnglish());
            } else {
                vo.setStyleName(styleEnum.getChinese());
            }
        }
        if (null != vo.getUserBrandDna()) {
            BrandDNA brandDNA = brandDNAMapper.selectById(vo.getUserBrandDna());
            vo.setUserBrandDnaName(brandDNA.getBrandName());
            vo.setUserBrandDnaImg(minioUtil.getPreSignedUrl(brandDNA.getBrandLogo(), 24 * 60));
        }
        return vo;
    }

    @Override
    public List<ModelsVO> getMannequins(String sex, String style, String ageGroup) {
        AuthPrincipalVo userInfo = UserContext.getUserHolder();
        List<ModelsVO> result = new ArrayList<>();
        QueryWrapper<Library> libraryQueryWrapper = new QueryWrapper<>();
        libraryQueryWrapper.lambda()
                .eq(Library::getAccountId, userInfo.getId())
                .eq(Library::getLevel1Type, LibraryLevel1TypeEnum.MODELS.getRealName())
                .eq(Library::getLevel2Type, sex)
                .and(wrapper -> wrapper
                        .eq(Library::getLevel3Type, ageGroup)
                        .or()
                        .eq(Library::getAgeGroup, ageGroup)
                )
                .orderByDesc(Library::getCreateDate);
        List<Library> libraries = libraryMapper.selectList(libraryQueryWrapper);
        if (!CollectionUtils.isEmpty(libraries)) {
            List<ModelVO> modelVOList = new ArrayList<>();
            for (Library library : libraries) {
                ModelVO modelVO = new ModelVO();
                modelVO.setId(library.getId());
                modelVO.setUrl(library.getUrl());
                modelVO.setPresignedUrl(minioUtil.getPreSignedUrl(library.getUrl(), 24 * 60));
                modelVOList.add(modelVO);
            }
            ModelsVO vo = new ModelsVO();
            vo.setModelList(modelVOList);
            vo.setType(MannequinType.LIBRARY.getValue());
            result.add(vo);
        }
        QueryWrapper<SysFile> sysFileQueryWrapper = new QueryWrapper<>();
//        sysFileQueryWrapper.lambda().eq(SysFile::getLevel1Type, SysFileLevel1TypeEnum.ACCESSORIES.getRealName());
//        sysFileQueryWrapper.lambda().eq(SysFile::getLevel2Type, SysFileLevel2TypeEnum.BODY.getRealName());
        sysFileQueryWrapper.lambda().eq(SysFile::getLevel1Type, "Models");
        // 重复模特
        sysFileQueryWrapper.lambda().ne(SysFile::getId, 1020366);
        sysFileQueryWrapper.lambda().eq(SysFile::getLevel2Type, sex);

        QueryWrapper<SysFileExtra> sysFileExtraQueryWrapper = new QueryWrapper<>();
        sysFileExtraQueryWrapper.lambda().eq(SysFileExtra::getAgeGroup, ageGroup);
        List<SysFileExtra> sysFileExtras = sysFileExtraMapper.selectList(sysFileExtraQueryWrapper);
        if (!CollectionUtils.isEmpty(sysFileExtras)) {
            Set<Long> collect = sysFileExtras.stream().map(SysFileExtra::getSysId).collect(Collectors.toSet());
            if (!CollectionUtils.isEmpty(collect)) {
                sysFileQueryWrapper.lambda().in(SysFile::getId, collect);
            }
        }

        if (!StringUtils.isEmpty(style)) {
            sysFileQueryWrapper.lambda().eq(SysFile::getLevel3Type, style);
        }
//        else {
//            sysFileQueryWrapper.lambda().eq(SysFile::getLevel3Type, style);
//            sysFileQueryWrapper.lambda().isNull(SysFile::getLevel3Type);
//        }

        List<SysFile> sysFileList = sysFileMapper.selectList(sysFileQueryWrapper);
        if (!CollectionUtils.isEmpty(sysFileList)) {
            List<ModelVO> modelVOList = new ArrayList<>();
            for (SysFile sysFile : sysFileList) {
                ModelVO modelVO = new ModelVO();
                modelVO.setId(sysFile.getId());
                modelVO.setUrl(sysFile.getUrl());
                modelVO.setPresignedUrl(minioUtil.getPreSignedUrl(sysFile.getUrl(), 24 * 60));
                modelVOList.add(modelVO);
            }
            ModelsVO vo = new ModelsVO();
            vo.setModelList(modelVOList);
            vo.setType(MannequinType.SYSTEM.getValue());
            result.add(vo);
        }
        return result;
    }

    @Override
    public void systemFileCopy() {
        QueryWrapper<SysFile> sysFileQueryWrapper = new QueryWrapper<>();
        // 迁移系统表图片
        List<SysFile> sysFiles = sysFileMapper.selectList(sysFileQueryWrapper);
        for (SysFile sysFile : sysFiles) {
            String url = sysFile.getUrl();
            if (url.contains("/download/")) {
                String[] downloads = url.split("/download/");
                if (downloads.length == 2) {
                    String linux = downloads[1];
                    String windows = linux.replaceAll("/", "\\\\");
                    String path = "C:\\workspace\\fileData\\file\\" + windows;
                    File file = FileUtil.getFile(path);
                    if (file != null) {
                        String uploadMinioPath = sysFile.getLevel1Type().toLowerCase() + "/" + sysFile.getLevel2Type().toLowerCase() + "/" + file.getName();
                        String bucketName = sysImage;
                        boolean b = minioUtil.doesObjectExist(bucketName, uploadMinioPath);
                        if (!b) {
                            FileItem a = getMultipartFile(file, file.getName());
                            MultipartFile multipartFile = new CommonsMultipartFile(a);
                            minioUtil.upload(bucketName, uploadMinioPath, multipartFile, "");
                        }
                        sysFile.setUrl(bucketName + "/" + uploadMinioPath);
                        sysFileMapper.updateById(sysFile);
                    }
                }
            }
        }
        // 迁移用户上传library图片
        QueryWrapper<Library> libraryQueryWrapper = new QueryWrapper<>();
        List<Library> libraryList = libraryMapper.selectList(libraryQueryWrapper);
        for (Library o : libraryList) {
            String url = o.getUrl();
            if (url.contains("/download/")) {
                String[] downloads = url.split("/download/");
                if (downloads.length == 2) {
                    String linux = downloads[1];
                    String windows = linux.replaceAll("/", "\\\\");
                    String path = "C:\\workspace\\fileData\\file\\" + windows;
                    File file = FileUtil.getFile(path);
                    if (file != null) {
                        StringBuilder sb = new StringBuilder();
                        if (StringUtils.isEmpty(o.getLevel2Type())) {
                            sb.append(o.getAccountId() + "/").append(o.getLevel1Type().toLowerCase() + "/").append(file.getName());
                        } else {
                            sb.append(o.getAccountId() + "/").append(o.getLevel1Type().toLowerCase() + "/").append(o.getLevel2Type().toLowerCase() + "/").append(file.getName());
                        }
                        String bucketName = users;
                        boolean b = minioUtil.doesObjectExist(bucketName, sb.toString());
                        if (!b) {
                            FileItem a = getMultipartFile(file, file.getName());
                            MultipartFile multipartFile = new CommonsMultipartFile(a);
                            minioUtil.upload(bucketName, sb.toString(), multipartFile, "");
                        }
                        o.setUrl(bucketName + "/" + sb);
                        libraryMapper.updateById(o);
                    }
                }
            }
        }
        // 迁移like相关数据
//        QueryWrapper<UserLike> userLikeQueryWrapper = new QueryWrapper<>();
//        List<UserLike> userLikeList = userLikeMapper.selectList(userLikeQueryWrapper);
//        if (!CollectionUtils.isEmpty(userLikeList)) {
//            userLikeList.forEach(o -> {
//                Long userLikeId = o.getId();
//            });
//        }
    }

    @Override
    public void moveFile() {
        QueryWrapper<SysFile> sysFileQw = new QueryWrapper<>();
        sysFileQw.lambda().eq(SysFile::getLevel1Type, "Images");
        List<SysFile> sysFiles = sysFileMapper.selectList(sysFileQw);
        for (SysFile sysFile : sysFiles) {
            if (sysFile.getUrl().contains("/female")) {
                continue;
            }
            String[] urls = sysFile.getUrl().split("/images");
            String newUrl = urls[0] + "/images/female" + urls[1];
            sysFile.setUrl(newUrl);
            sysFileMapper.updateById(sysFile);
        }

        QueryWrapper<Library> libraryQw = new QueryWrapper<>();
        libraryQw.lambda().eq(Library::getLevel1Type, "Sketchboard");
        List<Library> libraryList = libraryMapper.selectList(libraryQw);
        for (Library library : libraryList) {
            String oldUrl = library.getUrl();
            if (oldUrl.contains("/sketchboard")) {
                String[] oldUrls = oldUrl.split("/sketchboard");
                String newUrl = oldUrls[0] + "/sketchboard/female" + oldUrls[1];
                library.setUrl(newUrl);
                libraryMapper.updateById(library);
            } else if (oldUrl.contains("/images")) {
                String[] oldUrls = oldUrl.split("/images");
                String newUrl = oldUrls[0] + "/images/female" + oldUrls[1];
                library.setUrl(newUrl);
                libraryMapper.updateById(library);
            }
        }

        QueryWrapper<Library> modelQw = new QueryWrapper<>();
        modelQw.lambda().eq(Library::getLevel1Type, "Models");
        List<Library> modelList = libraryMapper.selectList(modelQw);
        for (Library library : modelList) {
            String oldUrl = library.getUrl();
            if (oldUrl.contains("/models")) {
                String[] oldUrls = oldUrl.split("/models");
                String newUrl = oldUrls[0] + "/models/female" + oldUrls[1];
                library.setUrl(newUrl);
                libraryMapper.updateById(library);
            }
        }
    }

    @Autowired
    private AttributeRetrievalMapper attributeRetrievalMapper;


    @Override
    @Transactional
    public void maleDataInsert() throws FileNotFoundException {
        String directoryPath = "C:\\Users\\39093\\Desktop\\generated_sketch_gemini_updated_regendered\\unisex\\Post_apocalyptic";
        List<File> pngFiles = getPNGFiles(directoryPath);
        for (File pngFile : pngFiles) {
            String category = Paths.get(directoryPath).getFileName().toString();
            String fileName = category + "_2_" + pngFile.getName();
            String tableName = null;
            SysFile sysFile = new SysFile();
            sysFile.setName(fileName);
            sysFile.setLevel1Type("Images");

            AttributeRetrieval attributeRetrievalAttrDict = new AttributeRetrieval();

            attributeRetrievalAttrDict.setStyle("POST_APOCALYPTIC");
            String absolutePath = pngFile.getAbsolutePath();
            StringBuilder sb = new StringBuilder();
            sb.append("aida-sys-image/images");
            if (absolutePath.contains("Coat_Jacket") || absolutePath.contains("coat_jacket")) {
                if (absolutePath.contains("\\male")) {
                    tableName = "male_outwear";
                    sb.append("/male/outwear/");
                    sysFile.setLevel3Type("Male");
                } else if (absolutePath.contains("\\female")) {
                    tableName = "female_outwear";
                    sb.append("/female/outwear/");
                    sysFile.setLevel3Type("Female");
                } else if (absolutePath.contains("\\unisex")) {
                    tableName = "female_outwear";
                    sb.append("/female/outwear/");
                    sysFile.setLevel3Type("Female");
                }
                sysFile.setLevel2Type("Outwear");
                attributeRetrievalAttrDict.setImgName("outwear/" + fileName);
            }
            if (absolutePath.contains("Pants") || absolutePath.contains("pants")) {
                if (absolutePath.contains("\\male")) {
                    tableName = "male_bottoms";
                    sb.append("/male/bottoms/");
                    sysFile.setLevel3Type("Male");
                } else if (absolutePath.contains("\\female")) {
                    tableName = "female_trousers";
                    sb.append("/female/trousers/");
                    sysFile.setLevel3Type("Female");
                } else if (absolutePath.contains("\\unisex")) {
                    tableName = "female_trousers";
                    sb.append("/female/trousers/");
                    sysFile.setLevel3Type("Female");
                }
                sysFile.setLevel2Type("Trousers");
                attributeRetrievalAttrDict.setImgName("trousers/" + fileName);
            }
            if (absolutePath.contains("Top_Shirt") || absolutePath.contains("top_shirt")) {
                if (absolutePath.contains("\\male")) {
                    tableName = "male_tops";
                    sb.append("/male/tops/");
                    sysFile.setLevel3Type("Male");
                } else if (absolutePath.contains("\\female")) {
                    tableName = "female_blouse";
                    sb.append("/female/blouse/");
                    sysFile.setLevel3Type("Female");
                } else if (absolutePath.contains("\\unisex")) {
                    tableName = "female_blouse";
                    sb.append("/female/blouse/");
                    sysFile.setLevel3Type("Female");
                }
                sysFile.setLevel2Type("Blouse");
                attributeRetrievalAttrDict.setImgName("blouse/" + fileName);
            }
            if (absolutePath.contains("Dress") || absolutePath.contains("dress")) {
                tableName = "female_dress";
                sb.append("/female/dress/");
                sysFile.setLevel2Type("Dress");
                sysFile.setLevel3Type("Female");
                attributeRetrievalAttrDict.setImgName("dress/" + fileName);
            }
            if (absolutePath.contains("skirt") || absolutePath.contains("Skirt")) {
                tableName = "female_skirt";
                sb.append("/female/skirt/");
                sysFile.setLevel2Type("Skirt");
                sysFile.setLevel3Type("Female");
                attributeRetrievalAttrDict.setImgName("skirt/" + fileName);
            }
            sb.append(fileName);
            String url = sb.toString();
            sysFile.setUrl(url);
            sysFile.setMd5(MD5Utils.encryptFile(new FileInputStream(pngFile)));
            attributeRetrievalMapper.insertSketch(attributeRetrievalAttrDict, tableName);
            sysFile.setCreateDate(new Date());
            sysFile.setId(null);
            sysFileMapper.insert(sysFile);
            FileItem a = getMultipartFile(pngFile, fileName);
            MultipartFile multipartFile = new CommonsMultipartFile(a);
            minioUtil.upload(url.substring(0, 14), url.substring(15), multipartFile, "");
            System.out.println("上传成功url:" + url);
            if (absolutePath.contains("unisex")) {
                if (tableName.equals("female_outwear")) {
                    tableName = "male_outwear";
                    url = url.replace("/female/outwear/", "/male/outwear/");
                } else if (tableName.equals("female_blouse")) {
                    tableName = "male_tops";
                    attributeRetrievalAttrDict.setImgName("tops/" + fileName);
                    sysFile.setLevel2Type("Tops");
                    url = url.replace("/female/blouse/", "/male/tops/");
                } else if (tableName.equals("female_trousers")) {
                    tableName = "male_bottoms";
                    attributeRetrievalAttrDict.setImgName("bottoms/" + fileName);
                    sysFile.setLevel2Type("Bottoms");
                    url = url.replace("/female/trousers/", "/male/bottoms/");
                }
                minioUtil.upload(url.substring(0, 14), url.substring(15), multipartFile, "");
                sysFile.setLevel3Type("Male");
                sysFile.setId(null);
                sysFile.setUrl(url);
                sysFileMapper.insert(sysFile);
                attributeRetrievalMapper.insertSketch(attributeRetrievalAttrDict, tableName);
                System.out.println("上传成功url:" + url);
            }

        }
        System.out.println("结束");
    }

    //上传衣服

    public void maleDataInsert1() throws FileNotFoundException {
        String directoryPath = "C:\\Users\\39093\\Desktop\\generated_sketch_gemini_updated_regendered";
        List<File> pngFiles = getPNGFiles(directoryPath);
        for (File pngFile : pngFiles) {
            SysFile sysFile = new SysFile();
            String fileName = pngFile.getName();
            sysFile.setName(fileName);
            sysFile.setLevel1Type("Images");
            sysFile.setLevel3Type("Male");
            StringBuilder sb = new StringBuilder();
            sb.append("aida-sys-image/images/male");
            String absolutePath = pngFile.getAbsolutePath();
            if (absolutePath.contains("bottom")) {
                sysFile.setLevel2Type("Bottoms");
                sb.append("/bottoms/");
            } else if (absolutePath.contains("top")) {
                sysFile.setLevel2Type("Tops");
                sb.append("/tops/");
            } else if (absolutePath.contains("outer")) {
                sysFile.setLevel2Type("Outwear");
                sb.append("/outwear/");
            }
            sb.append(fileName);
            String url = sb.toString();
            sysFile.setUrl(url);
            sysFile.setMd5(MD5Utils.encryptFile(new FileInputStream(pngFile)));
//            boolean b = minioUtil.doesObjectExist("aida-sys-image", uploadMinioPath);
//            if (!b) {
//                FileItem a = getMultipartFile(file, file.getName());
//                MultipartFile multipartFile = new CommonsMultipartFile(a);
//                minioUtil.upload(bucketName, uploadMinioPath, multipartFile, "");
//            }
            FileItem a = getMultipartFile(pngFile, fileName);
            MultipartFile multipartFile = new CommonsMultipartFile(a);
            minioUtil.upload(url.substring(0, 14), url.substring(15), multipartFile, "");
            sysFile.setCreateDate(new Date());
            sysFileMapper.insert(sysFile);
        }
    }

    @Override
    public List<Long> delete(List<Workspace> workspaceList) {
        // 校验不能删除最后选择的workspace
        List<Long> deleteIds = workspaceList.stream().map(Workspace::getId).collect(Collectors.toList());
        QueryWrapper<Workspace> qw = new QueryWrapper<>();
        qw.lambda().in(Workspace::getId, deleteIds);
        qw.lambda().eq(Workspace::getIsLastIndex, 1);
        List<Workspace> workspaces = workspaceMapper.selectList(qw);
        if (!CollectionUtils.isEmpty(workspaces)) {
            throw new BusinessException("unable.to.delete.the.workspace.you.are.currently.using", ResultEnum.PROMPT.getCode());
        }
        workspaceMapper.deleteBatchIds(deleteIds);
        return deleteIds;
    }

    @Override
    public Workspace getCurrentWorkspace() {
        AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder();
        QueryWrapper<Workspace> qw = new QueryWrapper<>();
        qw.lambda().eq(Workspace::getAccountId, authPrincipalVo.getId());
        qw.lambda().eq(Workspace::getIsLastIndex, 1);
//        qw.lambda().eq(Workspace::getIsDeleted, 0);
        List<Workspace> workspaces = workspaceMapper.selectList(qw);
        if (CollectionUtils.isEmpty(workspaces)) {
            throw new BusinessException("workspace not found.");
        }
        return workspaces.get(0);
    }

    @Override
    public List<StyleVO> styleList() {
        AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder();
        QueryWrapper<Style> qw = new QueryWrapper<>();
        List<Style> styles = styleMapper.selectList(qw);
        List<StyleVO> styleVOS = CopyUtil.copyList(styles, StyleVO.class);
        for (StyleVO styleVO : styleVOS) {
            StyleEnum styleEnum = StyleEnum.fromName(styleVO.getName());
            if (authPrincipalVo.getLanguage().equals(Language.ENGLISH.name())) {
                styleVO.setValue(styleEnum.getEnglish());
            } else {
                styleVO.setValue(styleEnum.getChinese());
            }
        }
        return styleVOS;
    }

    @Override
    @Transactional
    public SaveOrUpdateProjectVO saveOrUpdateProject(ProjectDTO projectDTO) {
        SaveOrUpdateProjectVO vo = new SaveOrUpdateProjectVO();
        AuthPrincipalVo userInfo = UserContext.getUserHolder();
        if (projectDTO.getId() != null) {
            Long projectId = projectDTO.getId();

            if (projectDTO.getName() != null) {
                Project project = projectMapper.selectById(projectId);
                project.setName(projectDTO.getName());
                projectMapper.updateById(project);
            }

            if (Objects.nonNull(projectDTO.getWorkspace())) {
                QueryWrapper<Workspace> qw = new QueryWrapper<>();
                qw.lambda().eq(Workspace::getProjectId, projectDTO.getId());
                List<Workspace> workspaces = workspaceMapper.selectList(qw);

                if (CollectionUtils.isEmpty(workspaces)) {
                    throw new BusinessException("Lack of associated workspace.");
                } else {
                    Workspace workspace = workspaces.get(0);
                    Workspace workspaceNew = CopyUtil.copyObject(projectDTO.getWorkspace(), Workspace.class);
                    if (projectDTO.getProcess().equals(DesignProcess.SERIES_DESIGN.name()) || projectDTO.getProcess().equals(DesignProcess.SKETCH_COLLAGE_PROCESS.name())) {
                        if (!workspaceNew.getAgeGroup().equals(workspace.getAgeGroup()) || !workspaceNew.getSex().equals(workspace.getSex())) {
                            // 性别变更 清理sketch及模特
//                            deleteMannequinByProjectId(projectId);
                            if (!workspaceNew.getSex().equals(workspace.getSex())) {
//                                deleteSketchByProjectId(projectId);
                                SysFile sysFile = sysFileService.getOneBySex(projectDTO.getStyleId(), projectDTO.getWorkspace().getSex(), projectDTO.getWorkspace().getAgeGroup());
                                LambdaQueryWrapper<CollectionElement> queryWrapper = new LambdaQueryWrapper<CollectionElement>().eq(CollectionElement::getProjectId, projectId)
                                        .eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.MODEL.getRealName())
                                        .eq(CollectionElement::getLevel3Type, workspaceNew.getSex());
                                if (collectionElementMapper.selectCount(queryWrapper) == 0) {
                                    CollectionElement collectionElement = new CollectionElement();
                                    collectionElement.setAccountId(userInfo.getId());
                                    collectionElement.setProjectId(projectId);
                                    collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MODEL.getRealName());
                                    collectionElement.setLevel3Type(projectDTO.getWorkspace().getSex());
                                    collectionElement.setName(sysFile.getName());
                                    collectionElement.setUrl(sysFile.getUrl());
                                    collectionElement.setMd5(sysFile.getMd5());
                                    collectionElement.setCreateDate(new Date());
                                    collectionElement.setHasPin((byte) 0);
                                    collectionElementMapper.insert(collectionElement);
                                    CollectionElementRelModel collectionElementRelModel = new CollectionElementRelModel();
                                    collectionElementRelModel.setCollectionElementId(collectionElement.getId());
                                    collectionElementRelModel.setRelationId(sysFile.getId());
                                    collectionElementRelModel.setRelationType("System");
                                    collectionElementRelModelMapper.insert(collectionElementRelModel);
                                }

                            }
                        }

                    }
                    workspaceNew.setId(workspace.getId());
                    workspace.setUpdateTime(LocalDateTime.now());
                    workspaceMapper.updateById(workspaceNew);
                }
                if (projectDTO.getStyleId() != null) {
                    QueryWrapper<WorkspaceRelStyle> wRSQW = new QueryWrapper<>();
                    wRSQW.lambda().eq(WorkspaceRelStyle::getWorkspaceId, projectDTO.getWorkspace().getId());
                    List<WorkspaceRelStyle> workspaceRelStyles = workspaceRelStyleMapper.selectList(wRSQW);
                    if (CollectionUtils.isEmpty(workspaceRelStyles)) {
                        WorkspaceRelStyle rel = new WorkspaceRelStyle();
                        rel.setWorkspaceId(projectDTO.getWorkspace().getId());
                        rel.setStyleId(projectDTO.getStyleId());
                        workspaceRelStyleMapper.insert(rel);
                    } else {
                        WorkspaceRelStyle workspaceRelStyleOld = workspaceRelStyles.get(0);
                        if (!Objects.equals(workspaceRelStyleOld.getStyleId(), projectDTO.getStyleId())) {
                            workspaceRelStyleOld.setStyleId(projectDTO.getStyleId());
                            workspaceRelStyleMapper.updateById(workspaceRelStyleOld);
                        }
                    }
                } else {
                    QueryWrapper<WorkspaceRelStyle> wRSQW = new QueryWrapper<>();
                    wRSQW.lambda().eq(WorkspaceRelStyle::getWorkspaceId, projectDTO.getWorkspace().getId());
                    List<WorkspaceRelStyle> workspaceRelStyles = workspaceRelStyleMapper.selectList(wRSQW);
                    if (!CollectionUtils.isEmpty(workspaceRelStyles)) {
                        workspaceRelStyleMapper.deleteBatchIds(workspaceRelStyles);
                    }
                }
                Long workspaceId = workspaceService.getByProjectId(projectId);
                WorkspaceVO byIdForProject = workspaceService.getByIdForProject(workspaceId);
                vo.setWorkspaceVO(byIdForProject);
            }
            vo.setId(projectId);
            return vo;
        } else {
            Project project = CopyUtil.copyObject(projectDTO, Project.class);
            project.setAccountId(userInfo.getId());
            LocalDateTime now = LocalDateTime.now();
            if (StringUtil.isNullOrEmpty(project.getName())) {
                Long seq = redisUtil.increaseCount(UNNAMED_PROJECT_SEQ + userInfo.getId());
                project.setName("Untitled_" + seq);
            }
            project.setCreateTime(now);
            project.setUpdateTime(now);
            project.setOriginal(1);
            projectMapper.insert(project);

            if (Objects.nonNull(projectDTO.getWorkspace())) {
                Workspace workspace = CopyUtil.copyObject(projectDTO.getWorkspace(), Workspace.class);
                workspace.setIsLastIndex(0);
                workspace.setAccountId(userInfo.getId());
                workspace.setProjectId(project.getId());
                workspace.setCreateTime(LocalDateTime.now());
                workspace.setUpdateTime(LocalDateTime.now());

                if (projectDTO.getProcess().equals(DesignProcess.SERIES_DESIGN.name()) || projectDTO.getProcess().equals(DesignProcess.SKETCH_COLLAGE_PROCESS.name())) {
                    SysFile sysFile = sysFileService.getOneBySex(projectDTO.getStyleId(), projectDTO.getWorkspace().getSex(), projectDTO.getWorkspace().getAgeGroup());
                    CollectionElement collectionElement = new CollectionElement();
                    collectionElement.setAccountId(userInfo.getId());
                    collectionElement.setProjectId(project.getId());
                    collectionElement.setLevel1Type(CollectionLevel1TypeEnum.MODEL.getRealName());
                    collectionElement.setLevel3Type(projectDTO.getWorkspace().getSex());
                    collectionElement.setName(sysFile.getName());
                    collectionElement.setUrl(sysFile.getUrl());
                    collectionElement.setMd5(sysFile.getMd5());
                    collectionElement.setCreateDate(new Date());
                    collectionElement.setHasPin((byte) 0);
                    collectionElementMapper.insert(collectionElement);
                    CollectionElementRelModel collectionElementRelModel = new CollectionElementRelModel();
                    collectionElementRelModel.setCollectionElementId(collectionElement.getId());
                    collectionElementRelModel.setRelationId(sysFile.getId());
                    collectionElementRelModel.setRelationType("System");
                    collectionElementRelModelMapper.insert(collectionElementRelModel);
                    if (projectDTO.getWorkspace().getSex().equals(Sex.FEMALE.getValue())) {
                        workspace.setMannequinFemaleId(sysFile.getId());
                        workspace.setMannequinFemaleType("System");
                    } else {
                        workspace.setMannequinMaleId(sysFile.getId());
                        workspace.setMannequinMaleType("System");
                    }
                }

                workspaceMapper.insert(workspace);

                if (projectDTO.getStyleId() != null) {
                    WorkspaceRelStyle rel = new WorkspaceRelStyle();
                    rel.setWorkspaceId(workspace.getId());
                    rel.setStyleId(projectDTO.getStyleId());
                    workspaceRelStyleMapper.insert(rel);
                }
                WorkspaceVO byIdForProject = workspaceService.getByIdForProject(workspace.getId());
                vo.setWorkspaceVO(byIdForProject);
            }
            vo.setId(project.getId());
            return vo;
        }
    }

    private void deleteSketchByProjectId(Long projectId) {
        QueryWrapper<CollectionElement> qw = new QueryWrapper<>();
        qw.lambda().eq(CollectionElement::getProjectId, projectId);
        qw.lambda().eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName());
        collectionElementMapper.delete(qw);
    }

    private void deleteMannequinByProjectId(Long projectId) {
        QueryWrapper<CollectionElement> qw = new QueryWrapper<>();
        qw.lambda().eq(CollectionElement::getProjectId, projectId);
        qw.lambda().eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.MODEL.getRealName());
        collectionElementMapper.delete(qw);
    }

    @Override
    public Long getByProjectId(Long projectId) {
        QueryWrapper<Workspace> qw = new QueryWrapper<>();
        qw.lambda().eq(Workspace::getProjectId, projectId);
        List<Workspace> workspaceList = workspaceMapper.selectList(qw);
        if (CollectionUtils.isEmpty(workspaceList)) {
            return null;
        }
        return workspaceList.get(0).getId();
    }

    public Workspace getWSByProjectId(Long projectId) {
        QueryWrapper<Workspace> qw = new QueryWrapper<>();
        qw.lambda().eq(Workspace::getProjectId, projectId);
        List<Workspace> workspaceList = workspaceMapper.selectList(qw);
        if (CollectionUtils.isEmpty(workspaceList)) {
            return null;
        }
        return workspaceList.get(0);
    }

    @Override
    public String getProjectSexById(Long projectId) {
        LambdaQueryWrapper<Workspace> workspaceLambdaQueryWrapper = new LambdaQueryWrapper<>();
        workspaceLambdaQueryWrapper.eq(Workspace::getProjectId, projectId).select(Workspace::getSex);
        Workspace workspace = workspaceMapper.selectOne(workspaceLambdaQueryWrapper);
        if (workspace != null) {
            return workspace.getSex();
        }
        return null;
    }

    @Override
    public String getStyleByProjectId(Long projectId) {
        return workspaceMapper.getStyleByProjectId(projectId);
    }

    // 由于在数据库中表设计问题，目前只能通过路径来判断项目中是否存在某一个模特
    public Boolean checkIfModelExistsInProject(String md5, Long projectId) {
        QueryWrapper<CollectionElement> qw = new QueryWrapper<>();
        qw.lambda().eq(CollectionElement::getProjectId, projectId)
                .eq(CollectionElement::getLevel1Type, CollectionLevel1TypeEnum.MODEL.getRealName())
                .eq(CollectionElement::getMd5, md5);

        List<CollectionElement> collectionElements = collectionElementMapper.selectList(qw);
        return collectionElements != null && !collectionElements.isEmpty();
    }

    public static List<File> getPNGFiles(String directoryPath) {
        List<File> pngFiles = new ArrayList<>();
        File directory = new File(directoryPath);

        if (directory.isDirectory()) {
            File[] subDirectories = directory.listFiles(File::isDirectory);

            if (subDirectories != null) {
                for (File subDirectory : subDirectories) {
                    File[] imageFiles = subDirectory.listFiles((dir, name) -> name.toLowerCase().endsWith(".png"));

                    if (imageFiles != null) {
                        for (File imageFile : imageFiles) {
                            pngFiles.add(imageFile);
                        }
                    }
                }
            }
        }

        return pngFiles;
    }

    private static FileItem getMultipartFile(File file, String fieldName) {
        // 使用 DiskFileItemFactory 创建一个 FileItemFactory
        FileItemFactory factory = new DiskFileItemFactory(16, null);

        // 使用 FileItemFactory 创建一个 FileItem 对象
        String mimeType = getMimeType(file);
        FileItem item = factory.createItem(fieldName, mimeType, true, file.getName());

        byte[] buffer = new byte[8192];
        int bytesRead;

        try (FileInputStream fis = new FileInputStream(file);
             OutputStream os = item.getOutputStream()) {
            // 从文件中读取数据并写入 FileItem
            while ((bytesRead = fis.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return item;
    }

    private static String getMimeType(File file) {
        try {
            return Files.probeContentType(file.toPath());
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    private List<BizJson> getEnumValues(Class clazz) {
        List<BizJson> kvs = new ArrayList<BizJson>();
        IEnumDisplay[] items = (IEnumDisplay[]) clazz.getEnumConstants();
        for (IEnumDisplay item : items) {
            kvs.add(new BizJson(item.getValue(), item.name(), BusinessException.getMessageFromResource(item.name())));
        }
        return kvs;
    }

    @Override
    public String getAgeGroupByProjectOrCollectionId(Long projectId, Long collectionId) {
        if (Objects.nonNull(projectId)) {
            Workspace workspace = getWSByProjectId(projectId);
            if (workspace != null && !StringUtil.isNullOrEmpty(workspace.getAgeGroup())) {
                return workspace.getAgeGroup();
            }
        } else if (Objects.nonNull(collectionId) && collectionId != 0) {
            List<CollectionElement> byCollectionId = getByCollectionId(collectionId);
            if (byCollectionId != null && !byCollectionId.isEmpty()) {
                projectId = byCollectionId.get(0).getProjectId();
                if (projectId != null && projectId != 0L) {
                    Workspace workspace = getWSByProjectId(projectId);
                    if (workspace != null && !StringUtil.isNullOrEmpty(workspace.getAgeGroup())) {
                        return workspace.getAgeGroup();
                    }
                }
            }
        }
        return AgeGroup.ADULT.getValue();
    }

    private List<CollectionElement> getByCollectionId(Long collectionId) {
        QueryWrapper<CollectionElement> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CollectionElement::getCollectionId, collectionId);
        return collectionElementMapper.selectList(queryWrapper);
    }

}
