package com.cmvr.vi.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmvr.common.exception.GlobalException;
import com.cmvr.common.utils.uuid.IdUtils;
import com.cmvr.vi.enums.ViCorpusEnum;
import com.cmvr.vi.mapper.ViCorpusMapper;
import com.cmvr.vi.model.domain.ViCorpus;
import com.cmvr.vi.model.vo.ViContinuousCorpusVO;
import com.cmvr.vi.model.vo.ViCorpusVO;
import com.cmvr.vi.service.IViCorpusService;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 语料库Service业务层处理
 *
 * @author cmvr-iot
 */
@Service
public class IViCorpusServiceImpl extends ServiceImpl<ViCorpusMapper, ViCorpus> implements IViCorpusService {

    @Override
    public ViCorpus selectViCorpusByCorpusId(Long corpusId) {
        return this.getById(corpusId);
    }

    @Override
    public List<ViCorpus> selectViCorpusList(ViCorpusVO viCorpusVO) {
        String corpusType = viCorpusVO.getType();
        if (ObjUtil.isEmpty(corpusType)) {
            throw new GlobalException("语料类型不能为空!");
        }
        LambdaQueryWrapper<ViCorpus> wrapper = Wrappers.lambdaQuery();

        // 如果是唤醒语料
        if (ViCorpusEnum.WAKEUP.name().equalsIgnoreCase(corpusType)) {
            wrapper.eq(ViCorpus::getType, ViCorpusEnum.WAKEUP);
        }

        // 如果是单次对话
        if (ViCorpusEnum.TEST.name().equalsIgnoreCase(corpusType)) {
            wrapper.eq(ViCorpus::getType, ViCorpusEnum.TEST)
                    .eq(ViCorpus::getContinuous, 1); // 只查单次
        }

        // 公共条件
        wrapper.like(ObjUtil.isNotEmpty(viCorpusVO.getVoiceType()), ViCorpus::getVoiceType, viCorpusVO.getVoiceType())
                .like(ObjUtil.isNotEmpty(viCorpusVO.getDialect()), ViCorpus::getDialect, viCorpusVO.getDialect())
                .like(ObjUtil.isNotEmpty(viCorpusVO.getCorpusName()), ViCorpus::getCorpusName, viCorpusVO.getCorpusName())
                .like(ObjUtil.isNotEmpty(viCorpusVO.getTextContent()), ViCorpus::getTextContent, viCorpusVO.getTextContent())
                .eq(ObjUtil.isNotEmpty(viCorpusVO.getStatus()), ViCorpus::getStatus, viCorpusVO.getStatus())
                .in(CollUtil.isNotEmpty(viCorpusVO.getParentIds()), ViCorpus::getParentId, viCorpusVO.getParentIds())
                .orderByAsc(ViCorpus::getSortOrder)
                .orderByDesc(ViCorpus::getUpdateTime);

        return this.list(wrapper);
    }


    @Override
    public List<ViContinuousCorpusVO> selectContinuousList(ViCorpusVO viCorpusVO) {
        // 查询父级
        MPJLambdaWrapper<ViCorpus> wrapper = new MPJLambdaWrapper<>();
        wrapper.select(ViCorpus::getParentId)
                .select(ViCorpus::getCorpusName)
                .select(ViCorpus::getVoiceType)
                .select(ViCorpus::getDialect)
                .eq(ViCorpus::getType, ViCorpusEnum.TEST)
                .eq(ViCorpus::getContinuous, 0)
                .like(ObjUtil.isNotEmpty(viCorpusVO.getVoiceType()), ViCorpus::getVoiceType, viCorpusVO.getVoiceType())
                .like(ObjUtil.isNotEmpty(viCorpusVO.getDialect()), ViCorpus::getDialect, viCorpusVO.getDialect())
                .like(ObjUtil.isNotEmpty(viCorpusVO.getCorpusName()), ViCorpus::getCorpusName, viCorpusVO.getCorpusName())
                .in(CollUtil.isNotEmpty(viCorpusVO.getParentIds()), ViCorpus::getParentId, viCorpusVO.getParentIds())
                .groupBy(ViCorpus::getParentId, ViCorpus::getVoiceType, ViCorpus::getDialect, ViCorpus::getCorpusName);

        List<ViContinuousCorpusVO> list = this.baseMapper.selectJoinList(ViContinuousCorpusVO.class, wrapper);

        // 查询 children 用 parentId 关联
        for (ViContinuousCorpusVO vo : list) {
            List<ViCorpus> children = this.list(
                    Wrappers.lambdaQuery(ViCorpus.class)
                            .eq(ViCorpus::getParentId, vo.getParentId())
                            .eq(ViCorpus::getContinuous, 0)
                            .eq(ViCorpus::getType, ViCorpusEnum.TEST)
                            .orderByAsc(ViCorpus::getSortOrder)
            );
            vo.setChildren(children);
            if (CollUtil.isNotEmpty(children)) {
                Integer sortParent = children.get(0).getSortParent();
                vo.setSortParent(sortParent);
            }
        }

        return list;
    }


    @Override
    public int insertViCorpus(ViCorpus viCorpus) {
        viCorpus.setParentId(IdUtils.fastSimpleUUID());
        return this.baseMapper.insert(viCorpus);
    }

    @Override
    public boolean insertBatch(List<ViCorpus> data) {
        data.forEach(v -> v.setParentId(IdUtils.fastSimpleUUID()));
        return this.saveBatch(data);
    }

    @Override
    public int updateViCorpus(ViCorpus viCorpus) {
        return this.baseMapper.updateById(viCorpus);
    }

    @Override
    public int deleteViCorpusByCorpusIds(Long[] corpusIds) {
        return this.baseMapper.deleteBatchIds(Arrays.asList(corpusIds));
    }

    @Override
    public int insertOrUpdateBatch(List<ViCorpus> data) {
        if (CollUtil.isEmpty(data)) {
            throw new IllegalArgumentException("data must not be null");
        }

        // 非空 id → 更新
        List<ViCorpus> updateList = data.stream()
                .filter(item -> item.getCorpusId() != null)
                .collect(Collectors.toList());

        // 空 id → 新增
        List<ViCorpus> insertList = data.stream()
                .filter(item -> item.getCorpusId() == null)
                .collect(Collectors.toList());

        if (!insertList.isEmpty()) {
            this.saveBatch(insertList);
        }

        // 批量更新（自定义 XML，返回影响行数）
        if (!updateList.isEmpty()) {
            for (ViCorpus viCorpus : updateList) {
                this.updateById(viCorpus);
            }
        }
        return data.size();
    }

    @Override
    public boolean insertContinuousViCorpus(ViContinuousCorpusVO viContinuousCorpusVO) {
        String parentId = IdUtils.fastSimpleUUID();
        List<ViCorpus> children = viContinuousCorpusVO.getChildren();
        children.forEach(v -> v.setParentId(parentId));
        return this.saveBatch(children);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateContinuousViCorpus(ViContinuousCorpusVO viContinuousCorpusVO) {
        String parentId = viContinuousCorpusVO.getParentId();

        // parentId 下现有 corpusId
        List<Long> dbIds = this.list(new LambdaQueryWrapper<ViCorpus>()
                        .select(ViCorpus::getCorpusId)
                        .eq(ViCorpus::getParentId, parentId))
                .stream()
                .map(ViCorpus::getCorpusId)
                .collect(Collectors.toList());

        List<ViCorpus> children = viContinuousCorpusVO.getChildren();

        // 新增、更新、保留
        List<ViCorpus> addList = new ArrayList<>();
        List<ViCorpus> updateList = new ArrayList<>();
        Set<Long> keepIds = new HashSet<>();

        for (ViCorpus child : children) {
            if (ObjUtil.isEmpty(child.getCorpusId())) {
                // 新增
                child.setParentId(parentId);
                addList.add(child);
            } else {
                // 更新
                updateList.add(child);
                keepIds.add(child.getCorpusId());
            }
        }

        // 要删除的
        List<Long> removeIds = dbIds.stream()
                .filter(id -> !keepIds.contains(id))
                .collect(Collectors.toList());

        if (!addList.isEmpty()) {
            this.saveBatch(addList);
        }
        if (!updateList.isEmpty()) {
            this.updateBatchById(updateList);
        }
        if (!removeIds.isEmpty()) {
            this.removeByIds(removeIds);
        }

        return addList.size() + updateList.size() + removeIds.size();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteViCorpusByParentIds(String[] parentIds) {
        if (parentIds == null || parentIds.length == 0) {
            return 0;
        }
        return this.baseMapper.delete(
                new LambdaQueryWrapper<ViCorpus>()
                        .in(ViCorpus::getParentId, Arrays.asList(parentIds))
        );
    }

    @Override
    public ViCorpus queryCorpusByParentId(String parentId) {
        LambdaQueryWrapper<ViCorpus> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ViCorpus::getParentId, parentId);
        return this.getOne(wrapper);
    }

    @Override
    public List<ViCorpus> queryCorpusInParentIds(List<String> parentIds) {
        LambdaQueryWrapper<ViCorpus> wrapper = Wrappers.lambdaQuery();
        wrapper.in(ViCorpus::getParentId, parentIds)
                .orderByAsc(ViCorpus::getSortOrder);
        return this.list(wrapper);
    }
}
