/**
 * 20241029 ©WANGKANG 1686617586@qq.com
 */

package com.taais.biz.service.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import cn.hutool.core.util.ObjectUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.taais.biz.constant.BizConstant;
import com.taais.common.core.config.TaaisConfig;
import com.taais.common.core.constant.Constants;
import com.taais.common.core.utils.MapstructUtils;
import com.taais.common.core.utils.StringUtils;
import com.taais.common.orm.core.page.PageQuery;
import com.taais.common.core.core.page.PageResult;
import com.taais.common.orm.core.service.impl.BaseServiceImpl;
import com.taais.system.domain.vo.SysOssVo;
import com.taais.system.service.ISysOssService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.taais.biz.mapper.DataSeqMapper;
import com.taais.biz.domain.DataSeq;
import com.taais.biz.domain.bo.DataSeqBo;
import com.taais.biz.domain.vo.DataSeqVo;
import com.taais.biz.service.IDataSeqService;

import static com.taais.biz.domain.table.DataSeqTableDef.DATA_SEQ;
import static com.taais.biz.utils.ZipUtils.unzip;

/**
 * 数据管理Service业务层处理
 *
 * @author wangkang
 * 2024-10-08
 */
@Service
public class DataSeqServiceImpl extends BaseServiceImpl<DataSeqMapper, DataSeq> implements IDataSeqService {
    @Autowired
    private ISysOssService ossService;
    @Resource
    private DataSeqMapper dataSeqMapper;

    @Override
    public QueryWrapper query() {
        return super.query().from(DATA_SEQ);
    }

    private QueryWrapper buildQueryWrapper(DataSeqBo dataSeqBo) {
        QueryWrapper queryWrapper = super.buildBaseQueryWrapper();
        queryWrapper.and(DATA_SEQ.NAME.like(dataSeqBo.getName()));
        queryWrapper.and(DATA_SEQ.DATA_TYPE.eq(dataSeqBo.getDataType()));
        queryWrapper.and(DATA_SEQ.FILE_TYPE.eq(dataSeqBo.getFileType()));
        queryWrapper.and(DATA_SEQ.OBJECT_TYPE.eq(dataSeqBo.getObjectType()));
        queryWrapper.and(DATA_SEQ.OBJECT_SUBTYPE.eq(dataSeqBo.getObjectSubtype()));
        queryWrapper.and(DATA_SEQ.BATCH_NUM.eq(dataSeqBo.getBatchNum()));
        queryWrapper.and(DATA_SEQ.SCENE.eq(dataSeqBo.getScene()));
        queryWrapper.and(DATA_SEQ.DATA_SOURCE.eq(dataSeqBo.getDataSource()));
        queryWrapper.and(DATA_SEQ.GATHER_TIME.eq(dataSeqBo.getGatherTime()));
        queryWrapper.and(DATA_SEQ.GATHER_SPOT.eq(dataSeqBo.getGatherSpot()));
        queryWrapper.and(DATA_SEQ.URL.eq(dataSeqBo.getUrl()));
        queryWrapper.and(DATA_SEQ.LOG.eq(dataSeqBo.getLog()));
        queryWrapper.and(DATA_SEQ.REMARKS.eq(dataSeqBo.getRemarks()));
        queryWrapper.and(DATA_SEQ.SUBSYSTEM.eq(dataSeqBo.getSubsystem()));

        return queryWrapper;
    }

    /**
     * 查询数据管理
     *
     * @param id 数据管理主键
     * @return 数据管理
     */
    @Override
    public DataSeqVo selectById(Long id) {
        return this.getOneAs(query().where(DATA_SEQ.ID.eq(id)), DataSeqVo.class);

    }

    /**
     * 查询数据管理列表
     *
     * @param dataSeqBo 数据管理Bo
     * @return 数据管理集合
     */
    @Override
    public List<DataSeqVo> selectList(DataSeqBo dataSeqBo) {
        QueryWrapper queryWrapper = buildQueryWrapper(dataSeqBo);
        return this.listAs(queryWrapper, DataSeqVo.class);
    }

    /**
     * 分页查询数据管理列表
     *
     * @param dataSeqBo 数据管理Bo
     * @return 分页数据管理集合
     */
    @Override
    public PageResult<DataSeqVo> selectPage(DataSeqBo dataSeqBo) {
        QueryWrapper queryWrapper = buildQueryWrapper(dataSeqBo);
        Page<DataSeqVo> page = this.pageAs(PageQuery.build(), queryWrapper, DataSeqVo.class);
        return PageResult.build(page);
    }

    /**
     * 新增数据管理
     *
     * @param dataSeqBo 数据管理Bo
     * @return 结果:true 操作成功，false 操作失败
     */
    @Override
    public boolean insert(DataSeqBo dataSeqBo) {
        // 检查input_oss_id是否存在
        if (ObjectUtil.isNull(dataSeqBo.getInputOssId())) {
            return false;
        }

        SysOssVo ossEntity = ossService.getById(dataSeqBo.getInputOssId());
        if (ObjectUtil.isNull(ossEntity)) {
            return false;
        }
        DataSeq dataSeq = MapstructUtils.convert(dataSeqBo, DataSeq.class);

        String filePath = ossEntity.getFileName();
        String localPath = TaaisConfig.getProfile();
        String resourcePath = localPath + StringUtils.substringAfter(filePath, Constants.RESOURCE_PREFIX);
        dataSeq.setFilePath(resourcePath);

        String unzipPath = resourcePath.substring(0, resourcePath.lastIndexOf(".")) + BizConstant.UNZIP_SUFFIX;
        unzip(dataSeq.getFilePath(), unzipPath);
        dataSeq.setUnzipPath(unzipPath);

        dataSeq.setUrl(ossEntity.getUrl());
        return this.save(dataSeq);// 使用全局配置的雪花算法主键生成器生成ID值
    }

    /**
     * 修改数据管理
     *
     * @param dataSeqBo 数据管理Bo
     * @return 结果:true 更新成功，false 更新失败
     */
    @Override
    public boolean update(DataSeqBo dataSeqBo) {
        DataSeq dataSeq = MapstructUtils.convert(dataSeqBo, DataSeq.class);
        if (ObjectUtil.isNotNull(dataSeq) && ObjectUtil.isNotNull(dataSeq.getId())) {
            boolean updated = this.updateById(dataSeq);
            return updated;
        }
        return false;
    }

    /**
     * 批量删除数据管理
     *
     * @param ids 需要删除的数据管理主键集合
     * @return 结果:true 删除成功，false 删除失败
     */
    @Transactional
    @Override
    public boolean deleteByIds(Long[] ids) {
        return this.removeByIds(Arrays.asList(ids));
    }

    @Override
    public List<String> getAllImages(Long inputOdssId) {
        // 检查input_oss_id是否存在
        if (ObjectUtil.isNull(inputOdssId)) {
            return null;
        }
        SysOssVo ossEntity = ossService.getById(inputOdssId);
        if (ObjectUtil.isNull(ossEntity)) {
            return null;
        }

        String filePath = ossEntity.getFileName();
        String localPath = TaaisConfig.getProfile();
        String resourcePath = localPath + StringUtils.substringAfter(filePath, Constants.RESOURCE_PREFIX);
        String unzipPath = resourcePath.substring(0, resourcePath.lastIndexOf(".")) + BizConstant.UNZIP_SUFFIX;

        String urlPrefix = ossEntity.getUrl().substring(0, ossEntity.getUrl().indexOf(Constants.RESOURCE_PREFIX) + Constants.RESOURCE_PREFIX.length());

        // 列出unzipPath下所有图片文件
        File directory = new File(unzipPath);

        List<String> imageList = new ArrayList<>();
        filterImages(imageList, directory, urlPrefix);
        return imageList;
    }

    public void filterImages(List<String> imageList, File path, String urlPrefix) {
        File[] files = path.listFiles();
        if (files == null || files.length == 0) {
            return;
        }
        List<String> tmpList = Arrays.asList(files).stream().filter(file -> file.isFile() && isImageFile(file)).map(file -> urlPrefix + file.getPath().substring(TaaisConfig.getProfile().length()).replaceAll("\\\\", "/")).toList();
        imageList.addAll(tmpList);

        for (File file : files) {
            if (file.isDirectory()) {
                filterImages(imageList, file, urlPrefix);
            }
        }
    }

    public static List<String> calculateImagePath(String urlPrefix, File path) {
        List<String> imageList = new ArrayList<>();
        File[] files = path.listFiles();
        if (files == null || files.length == 0) {
            return null;
        }
        List<String> tmpList = Arrays.asList(files).stream().filter(file -> file.isFile() && isImageFile(file)).map(file -> urlPrefix + file.getPath().substring(TaaisConfig.getProfile().length()).replaceAll("\\\\", "/")).toList();
        imageList.addAll(tmpList);
        return imageList;
    }

    public static List<String> calculateImagePath(String urlPrefix, String path) {
        File dir = new File(path);
        if (!dir.exists() || !dir.isDirectory()) {
            return null;
        }
        return calculateImagePath(urlPrefix, dir);
    }

    @Override
    public List<String> getImages(Long inputOdssId, String subsystem, Boolean isInput, String dir) {
        // 检查input_oss_id是否存在
        if (ObjectUtil.isNull(inputOdssId)) {
            return null;
        }
        SysOssVo ossEntity = ossService.getById(inputOdssId);
        if (ObjectUtil.isNull(ossEntity)) {
            return null;
        }

        String filePath = ossEntity.getFileName();
        String localPath = TaaisConfig.getProfile();
        String resourcePath = localPath + StringUtils.substringAfter(filePath, Constants.RESOURCE_PREFIX);
        String unzipPath = resourcePath.substring(0, resourcePath.lastIndexOf(".")) + BizConstant.UNZIP_SUFFIX + "/" + dir;
        String resultPath = resourcePath.substring(0, resourcePath.lastIndexOf(".")) + subsystem + "/" + dir;

        try {
            if (isInput) {
                String urlPrefix = ossEntity.getUrl().substring(0, ossEntity.getUrl().lastIndexOf(".")) + BizConstant.UNZIP_SUFFIX + "/" + dir;
                // 列出unzipPath下所有图片文件
                File directory = new File(unzipPath);
                File[] files = directory.listFiles();
                List<String> imageList = Arrays.asList(files).stream().filter(file -> isImageFile(file)).map(file -> urlPrefix + "/" + file.getName()).toList();
                return imageList;
            } else {
                String urlPrefix = ossEntity.getUrl().substring(0, ossEntity.getUrl().lastIndexOf(".")) + subsystem + "/" + dir;
                // 列出unzipPath下所有图片文件
                File directory = new File(resultPath);
                File[] files = directory.listFiles();
                List<String> imageList = Arrays.asList(files).stream().filter(file -> isImageFile(file)).map(file -> urlPrefix + "/" + file.getName()).toList();
                return imageList;
            }
        } catch (Exception e) {
            System.out.println("getImages error: " + e.getMessage());
            return new ArrayList<>();
        }
    }

    // 常见图片格式的后缀
    private static final String[] IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".tif", ".webp"};

    // 判断文件是否为常见图片格式
    public static boolean isImageFile(File file) {
        if (file.isDirectory()) {
            return false;
        }
        String fileName = file.getName().toLowerCase();
        for (String extension : IMAGE_EXTENSIONS) {
            if (fileName.endsWith(extension)) {
                return true;
            }
        }
        return false;
    }
}
