package top.continew.admin.business.service.impl;

import cn.crane4j.core.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import top.continew.admin.business.mapper.DigitalHumanMapper;
import top.continew.admin.business.mapper.EffectMapper;
import top.continew.admin.business.mapper.SubtitleItemMapper;
import top.continew.admin.business.mapper.SubtitleStyleMapper;
import top.continew.admin.business.model.entity.*;
import top.continew.admin.business.model.query.DigitalHumanPageQuery;
import top.continew.admin.business.model.query.DigitalHumanQuery;
import top.continew.admin.business.model.req.DigitalHumanReq;
import top.continew.admin.business.model.resp.DigitalHumanDetailResp;
import top.continew.admin.business.model.resp.DigitalHumanResp;
import top.continew.admin.business.service.DigitalHumanService;
import top.continew.starter.extension.crud.model.resp.PageResp;
import top.continew.starter.extension.crud.service.impl.BaseServiceImpl;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 数字人服务实现类
 *
 * @author 王志维
 * @since 2025/12/29
 */
@Service
@RequiredArgsConstructor
public class DigitalHumanServiceImpl extends BaseServiceImpl<DigitalHumanMapper, DigitalHuman, DigitalHumanResp, DigitalHumanDetailResp, DigitalHumanQuery, DigitalHumanReq> implements DigitalHumanService {

    private final DigitalHumanMapper digitalHumanMapper;
    private final SubtitleStyleMapper subtitleStyleMapper;
    private final SubtitleItemMapper subtitleItemMapper;
    private final EffectMapper effectMapper;

    @Override
    public List<DigitalHumanResp> list(DigitalHumanQuery query,
                                       top.continew.starter.extension.crud.model.query.SortQuery sortQuery) {
        LambdaQueryWrapper<DigitalHuman> wrapper = new LambdaQueryWrapper<>();
        if (query.getUserId() != null) {
            wrapper.eq(DigitalHuman::getUserId, query.getUserId());
        }
        if (query.getCopywriting() != null) {
            wrapper.like(DigitalHuman::getCopywriting, query.getCopywriting());
        }
        if (query.getGeneratedVoiceUrl() != null) {
            wrapper.eq(DigitalHuman::getGeneratedVoiceUrl, query.getGeneratedVoiceUrl());
        }
        if (query.getGeneratedFrameImageUrl() != null) {
            wrapper.eq(DigitalHuman::getGeneratedFrameImageUrl, query.getGeneratedFrameImageUrl());
        }
        if (query.getGeneratedVideoUrl() != null) {
            wrapper.eq(DigitalHuman::getGeneratedVideoUrl, query.getGeneratedVideoUrl());
        }

        return digitalHumanMapper.selectList(wrapper).stream().map(this::convertToResp).collect(Collectors.toList());
    }

    @Override
    public top.continew.starter.extension.crud.model.resp.PageResp<DigitalHumanResp> pageList(DigitalHumanQuery query,
                                                                                              DigitalHumanPageQuery pageQuery) {
        LambdaQueryWrapper<DigitalHuman> wrapper = new LambdaQueryWrapper<>();
        //query.setUserId(LoginHelper.getUserId().toString());
        if (query.getUserId() != null) {
            wrapper.eq(DigitalHuman::getUserId, query.getUserId());
        }
        if (query.getCopywriting() != null) {
            wrapper.like(DigitalHuman::getCopywriting, query.getCopywriting());
        }
        if (query.getGeneratedVoiceUrl() != null) {
            wrapper.eq(DigitalHuman::getGeneratedVoiceUrl, query.getGeneratedVoiceUrl());
        }
        if (query.getGeneratedFrameImageUrl() != null) {
            wrapper.eq(DigitalHuman::getGeneratedFrameImageUrl, query.getGeneratedFrameImageUrl());
        }
        if (query.getGeneratedVideoUrl() != null) {
            wrapper.eq(DigitalHuman::getGeneratedVideoUrl, query.getGeneratedVideoUrl());
        }

        wrapper.orderByDesc(DigitalHuman::getCreateTime);

        Page<DigitalHuman> page = new Page<>(pageQuery.getPage(), pageQuery.getSize());
        Page<DigitalHuman> result = digitalHumanMapper.selectPage(page, wrapper);

        PageResp<DigitalHumanResp> pageResp = new PageResp();
        pageResp.setTotal(result.getTotal());
        pageResp.setList(result.getRecords().stream().map(this::convertToResp).toList());
        return pageResp;
    }

    @Override
    public Long add(DigitalHumanReq req) {
        DigitalHuman digitalHuman = new DigitalHuman();
        // 只复制基本字段，不包括关联的列表字段
        digitalHuman.setUserId(req.getUserId());
        digitalHuman.setCopywriting(req.getCopywriting());
        digitalHuman.setGeneratedVoiceUrl(req.getGeneratedVoiceUrl());
        digitalHuman.setGeneratedFrameImageUrl(req.getGeneratedFrameImageUrl());
        digitalHuman.setGeneratedVideoUrl(req.getGeneratedVideoUrl());
        digitalHuman.setCreateTime(java.time.LocalDateTime.now());
        digitalHuman.setUpdateTime(java.time.LocalDateTime.now());
        digitalHumanMapper.insert(digitalHuman);

        // 保存字幕样式
        if (req.getSubtitleStyle() != null) {
            SubtitleStyle subtitleStyle = req.getSubtitleStyle();
            subtitleStyle.setDigitalHumanId(digitalHuman.getId());
            subtitleStyle.setCreateTime(java.time.LocalDateTime.now());
            subtitleStyle.setUpdateTime(java.time.LocalDateTime.now());
            subtitleStyleMapper.insert(subtitleStyle);
        }

        return digitalHuman.getId();
    }

    @Override
    public void delete(List<Long> ids) {
        for (Long id : ids) {
            // 删除关联的特效
            LambdaQueryWrapper<Effect> effectWrapper = new LambdaQueryWrapper<>();
            effectWrapper.eq(Effect::getDigitalHumanId, id);
            effectMapper.delete(effectWrapper);

            // 删除关联的字幕项
            LambdaQueryWrapper<SubtitleItem> subtitleItemWrapper = new LambdaQueryWrapper<>();
            subtitleItemWrapper.eq(SubtitleItem::getDigitalHumanId, id);
            subtitleItemMapper.delete(subtitleItemWrapper);

            // 删除关联的字幕样式
            LambdaQueryWrapper<SubtitleStyle> subtitleStyleWrapper = new LambdaQueryWrapper<>();
            subtitleStyleWrapper.eq(SubtitleStyle::getDigitalHumanId, id);
            subtitleStyleMapper.delete(subtitleStyleWrapper);
        }

        // 删除数字人
        digitalHumanMapper.deleteBatchIds(ids);
    }

    @Override
    public void update(DigitalHumanReq req, Long id) {
        DigitalHuman digitalHuman = new DigitalHuman();
        // 只复制基本字段，不包括关联的列表字段
        digitalHuman.setId(id);
        digitalHuman.setUserId(req.getUserId());
        digitalHuman.setCopywriting(req.getCopywriting());
        digitalHuman.setGeneratedVoiceUrl(req.getGeneratedVoiceUrl());
        digitalHuman.setGeneratedFrameImageUrl(req.getGeneratedFrameImageUrl());
        digitalHuman.setGeneratedVideoUrl(req.getGeneratedVideoUrl());
        digitalHuman.setUpdateTime(java.time.LocalDateTime.now());
        digitalHumanMapper.updateById(digitalHuman);

        // 更新或保存字幕样式
        if (req.getSubtitleStyle() != null) {
            LambdaQueryWrapper<SubtitleStyle> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SubtitleStyle::getDigitalHumanId, id);
            List<SubtitleStyle> existingStyles = subtitleStyleMapper.selectList(wrapper);

            SubtitleStyle subtitleStyle = req.getSubtitleStyle();
            subtitleStyle.setDigitalHumanId(id);
            subtitleStyle.setUpdateTime(java.time.LocalDateTime.now());

            if (existingStyles != null && !existingStyles.isEmpty()) {
                // 如果已存在样式记录，更新第一个记录
                subtitleStyle.setId(existingStyles.get(0).getId());
                subtitleStyleMapper.updateById(subtitleStyle);
            } else {
                // 如果不存在样式记录，创建新记录
                subtitleStyle.setCreateTime(java.time.LocalDateTime.now());
                subtitleStyleMapper.insert(subtitleStyle);
            }
        }
    }

    private DigitalHumanResp convertToResp(DigitalHuman digitalHuman) {
        DigitalHumanResp resp = new DigitalHumanResp();
        BeanUtils.copyProperties(digitalHuman, resp);
        // 处理关联数据
        List<SubtitleStyle> subtitleStyles = subtitleStyleMapper.selectList(new LambdaQueryWrapper<SubtitleStyle>()
            .eq(SubtitleStyle::getDigitalHumanId, digitalHuman.getId()));
        resp.setSubtitleStyle(CollectionUtils.isNotEmpty(subtitleStyles) ? subtitleStyles.get(0) : null);
        resp.setEffects(effectMapper.selectList(new LambdaQueryWrapper<Effect>()
            .eq(Effect::getDigitalHumanId, digitalHuman.getId())));
        resp.setSubtitles(subtitleItemMapper.selectList(new LambdaQueryWrapper<SubtitleItem>()
            .eq(SubtitleItem::getDigitalHumanId, digitalHuman.getId())));
        return resp;
    }
}