package cn.ey.biz.module.system.service.wiki;

import cn.ey.biz.common.pojo.PageResult;
import cn.ey.biz.framework.file.core.preview.FileAttribute;
import cn.ey.biz.framework.file.core.preview.FilePreviewFactory;
import cn.ey.biz.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.ey.biz.module.system.controller.admin.wiki.vo.*;
import cn.ey.biz.module.system.convert.wiki.WikiSpaceConvert;
import cn.ey.biz.module.system.dal.dataobject.file.FileDO;
import cn.ey.biz.module.system.dal.dataobject.wiki.WikiFileDO;
import cn.ey.biz.module.system.dal.dataobject.wiki.WikiImageDO;
import cn.ey.biz.module.system.dal.dataobject.wiki.WikiSpaceDO;
import cn.ey.biz.module.system.dal.mapper.wiki.WikiFileMapper;
import cn.ey.biz.module.system.dal.mapper.wiki.WikiImageMapper;
import cn.ey.biz.module.system.dal.mapper.wiki.WikiSpaceMapper;
import cn.ey.biz.module.system.dal.redis.file.FileDAO;
import cn.ey.biz.module.system.enums.wiki.WikiFileRefTypeEnum;
import cn.ey.biz.module.system.enums.wiki.WikiSpaceContentTypeEnum;
import cn.ey.biz.module.system.enums.wiki.WikiSpaceReleaseStatusEnum;
import cn.ey.biz.module.system.service.file.FileConfigService;
import cn.ey.biz.module.system.service.file.FileService;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class WikiSpaceServiceImpl implements WikiSpaceService {

    @Resource
    private WikiSpaceMapper wikiSpaceMapper;
    @Resource
    private WikiFileMapper wikiFileMapper;
    @Resource
    private WikiImageMapper wikiImageMapper;
    @Resource
    private FilePreviewFactory previewFactory;
    @Resource
    private FileConfigService fileConfigService;
    @Resource
    private FileService fileService;
    @Resource
    private FileDAO fileDAO;

    @Override
    @Transactional
    public void createWikiSpace(WikiSpaceCreateReqVO createReqVO) {
        try {
            WikiSpaceDO wikiSpace = WikiSpaceConvert.INSTANCE.convert(createReqVO);
            wikiSpaceMapper.insert(wikiSpace);
            //判断类型是否是上传文件
            String contentType = createReqVO.getContentType();
            if (StringUtils.equals(contentType, WikiSpaceContentTypeEnum.FILE.getValue())) {
                MultipartFile file = createReqVO.getUploadFile();
                createWikiFIle(file, wikiSpace.getId());
            }
        } catch (IOException e) {
            log.error("createWikiSpaceErr", e);
        }
    }

    void createWikiFIle(MultipartFile file, Long spaceId) throws IOException {
        //存储文件到本地
        //不满足后缀名的通过文件头验证
        //FileTypeCheck.checkFileBySuffixes(file, suffixes.split(","));
        //FileTypeCheck.checkFileByActualType(file, types.split(","));
        FileDO fileDO = fileService.createFile(file.getOriginalFilename(), null, IoUtil.readBytes(file.getInputStream()), "wikiSpaceUploadFile");
        //将文件保存到wikiFile表
        WikiFileDO wikiFileDO = new WikiFileDO();
        wikiFileDO.setRefId(spaceId);
        wikiFileDO.setRefType(WikiFileRefTypeEnum.SPACE.getValue());
        String fileName = fileDO.getName();
        wikiFileDO.setFileName(fileName);
        wikiFileDO.setFileSuffix(getFileSuffix(fileName));
        wikiFileDO.setFileSize(fileDO.getSize().longValue());
        wikiFileDO.setFilePath(fileDO.getPath());
        wikiFileDO.setFileUrl(fileDO.getUrl());
        wikiFileMapper.insert(wikiFileDO);
    }

    @Override
    @Transactional
    public void updateWikiSpace(@Valid WikiSpaceUpdateReqVO updateReqVO) {
        WikiSpaceDO wikiSpace = WikiSpaceConvert.INSTANCE.convert(updateReqVO);
        //之前的wikiSpace
        WikiSpaceDO oriWikeSpace = wikiSpaceMapper.selectById(updateReqVO.getId());
        String oriContentType = oriWikeSpace.getContentType();
        String contentType = updateReqVO.getContentType();
        Long spaceId = updateReqVO.getId();
        MultipartFile file = updateReqVO.getUploadFile();
        //如果之前的文件内容是文件上传
        try {
            if (StringUtils.equals(oriContentType, WikiSpaceContentTypeEnum.FILE.getValue())) {
                //如果现在是自定义，那么需要删除之前的wikiFile和wikiImage
                if (StringUtils.equals(contentType, WikiSpaceContentTypeEnum.WIKI.getValue())) {
                    WikiFileDO wikiFile = wikiFileMapper.selectOne(Wrappers.<WikiFileDO>lambdaQuery()
                            .eq(WikiFileDO::getRefId, spaceId)
                            .eq(WikiFileDO::getRefType, WikiFileRefTypeEnum.SPACE.getValue())
                    );
                    wikiFileMapper.deleteByRefIdAndType(wikiFile.getRefId(), WikiFileRefTypeEnum.SPACE.getValue());
                    wikiImageMapper.deleteByFileId(wikiFile.getId());
                } else {
                    //如果现在是文件上传，file不为空，则删除file并新增，删除image
                    if (file != null) {
                        WikiFileDO wikiFile = wikiFileMapper.selectOne(Wrappers.<WikiFileDO>lambdaQuery()
                                .eq(WikiFileDO::getRefId, spaceId)
                                .eq(WikiFileDO::getRefType, WikiFileRefTypeEnum.SPACE.getValue())
                        );
                        wikiImageMapper.deleteByFileId(wikiFile.getId());

                        wikiFileMapper.deleteByRefIdAndType(spaceId, WikiFileRefTypeEnum.SPACE.getValue());
                        createWikiFIle(file, wikiSpace.getId());
                    }
                }
            } else {
                //之前文件内容是自定义
                //如果现在是文件上传，走create逻辑
                if (StringUtils.equals(contentType, WikiSpaceContentTypeEnum.FILE.getValue())) {
                    createWikiFIle(file, wikiSpace.getId());
                }
            }
            wikiSpaceMapper.updateById(wikiSpace);
        } catch (IOException e) {
            log.error("updateWikiSpaceErr", e);
        }
    }

    @Override
    public WikiSpaceRespVO getWikiSpace(@Valid Long id) {
        WikiSpaceDO wikiSpace = wikiSpaceMapper.selectById(id);
        //判断类型是否是上传文件
        String contentType = wikiSpace.getContentType();
        WikiSpaceRespVO resp = WikiSpaceConvert.INSTANCE.convert(wikiSpace);
        if (StringUtils.equals(contentType, WikiSpaceContentTypeEnum.FILE.getValue())) {
            WikiFileDO wikiFile = wikiFileMapper.selectOne(Wrappers.<WikiFileDO>lambdaQuery()
                    .eq(WikiFileDO::getRefId, wikiSpace.getId())
                    .eq(WikiFileDO::getRefType, WikiFileRefTypeEnum.SPACE.getValue())
            );
            resp.setFile(wikiFile.getFileName());
        }
        return resp;
    }

    @Override
    public void deleteWikiSpace(@Valid Long id) {
        wikiSpaceMapper.deleteById(id);
    }

    @Override
    public PageResult<WikiSpaceRespVO> getWikiSpacePage(@Valid WikiSpacePageReqVO pageReqVO) {
        PageResult<WikiSpaceDO> wikiSpacePae = wikiSpaceMapper.selectPage(pageReqVO);
        PageResult<WikiSpaceRespVO> result = WikiSpaceConvert.INSTANCE.convertPage(wikiSpacePae);
        if (result != null) {
            List<WikiSpaceRespVO> list = result.getList();
            list.forEach(space -> {
                //查询file名称
                String contentType = space.getContentType();
                if (StringUtils.equals(contentType, WikiSpaceContentTypeEnum.FILE.getValue())) {
                    WikiFileDO file = wikiFileMapper.selectOne(Wrappers.<WikiFileDO>lambdaQuery()
                            .eq(WikiFileDO::getRefId, space.getId())
                            .eq(WikiFileDO::getRefType, WikiFileRefTypeEnum.SPACE.getValue())
                    );
                    if(file != null){
                        space.setFile(file.getFileName());
                    }
                }

            });
        }
        return result;
    }

    @Override
    @Transactional
    public void release(@Valid Long id) {
        WikiSpaceDO wikiSpace = wikiSpaceMapper.selectById(id);
        if (wikiSpace != null) {
            // 如果是文档类型
            if (WikiSpaceContentTypeEnum.FILE.getValue().equals(wikiSpace.getContentType())) {
                WikiFileDO file = wikiFileMapper.selectOne(Wrappers.<WikiFileDO>lambdaQuery()
                        .eq(WikiFileDO::getRefId, id)
                        .eq(WikiFileDO::getRefType, WikiFileRefTypeEnum.SPACE.getValue())
                );
                if (file != null) {
                    FileAttribute attribute = new FileAttribute();
                    attribute.setConfigId(fileConfigService.getMasterFileClient().getId());
                    attribute.setPath(file.getFilePath());
                    String fileName = file.getFileName();
                    String fileSuffix = getFileSuffix(fileName);
                    List<String> list = previewFactory.get(fileSuffix).filePreviewHandle(attribute);
                    // 伪批量提交
                    List<WikiImageDO> entities = Lists.newArrayList();
                    for (int i = 0; i < list.size(); i++) {
                        WikiImageDO image = new WikiImageDO()
                                .setImageUrl(list.get(i))
                                .setFileId(file.getId())
                                .setSeqNo(i);
                        entities.add(image);
                    }
                    wikiImageMapper.insertBatch(entities);
                }
            }
            wikiSpace.setReleaseStatus(WikiSpaceReleaseStatusEnum.RELEASE.getValue());
            wikiSpaceMapper.updateById(wikiSpace);
        }
    }

    String getFileSuffix(String fileName) {
        int index = fileName.lastIndexOf(".");
        return fileName.substring(index + 1).toLowerCase();
    }

    @Override
    public List<WikiSpaceRespVO> getListByType(@Valid WikiSpaceTypeReqVO reqVO) {
        List<WikiSpaceDO> wikiSpaceList = wikiSpaceMapper.selectList(reqVO);
        return WikiSpaceConvert.INSTANCE.convertSpaceList(wikiSpaceList);
    }

    @Override
    public List<String> getImageById(Long id) {
        List<String> wikiImageList = new ArrayList<>();
        //判断是否是文件上传
        WikiSpaceDO wikiSpaceDO = wikiSpaceMapper.selectById(id);
        String contentType = wikiSpaceDO.getContentType();
        if (StringUtils.equals(contentType, WikiSpaceContentTypeEnum.WIKI.getValue())) {
            return wikiImageList;
        }
        WikiFileDO wikiFileDO = wikiFileMapper.selectOne(new LambdaQueryWrapperX<WikiFileDO>()
                .eqIfPresent(WikiFileDO::getRefId, id));
        List<WikiImageDO> wikiImageDo = wikiImageMapper.selectList(new LambdaQueryWrapperX<WikiImageDO>()
                .eqIfPresent(WikiImageDO::getFileId, wikiFileDO.getId()));
        // 存储客户端标识
        Long configId = fileConfigService.getMasterFileClient().getId();
        for (WikiImageDO wikiImage : wikiImageDo) {
            String uuid = UUID.fastUUID().toString();
            wikiImageList.add(String.format("/infra/file/temp/%s/get/%s", configId, uuid)); //
            fileDAO.set(configId, uuid, wikiImage.getImageUrl());
        }
        return wikiImageList;
    }


}
