package com.ruoyi.zdsz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.annotation.DynamicName;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.framework.obs.ObsService;
import com.ruoyi.zdsz.domain.ZEngiineeringPhoto;
import com.ruoyi.zdsz.domain.bo.*;
import com.ruoyi.zdsz.domain.vo.*;
import com.ruoyi.zdsz.service.IZEngiineeringPhotoService;
import com.ruoyi.zdsz.service.IZEngineeringNodeService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.zdsz.domain.ZEngineeringPipeJacking;
import com.ruoyi.zdsz.mapper.ZEngineeringPipeJackingMapper;
import com.ruoyi.zdsz.service.IZEngineeringPipeJackingService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 顶管工程Service业务层处理
 *
 * @author ruoyi
 * @date 2024-01-02
 */
@RequiredArgsConstructor
@Service
public class ZEngineeringPipeJackingServiceImpl implements IZEngineeringPipeJackingService {

    private final ZEngineeringPipeJackingMapper baseMapper;

    @Autowired
    private IZEngineeringNodeService nodeService;
    @Autowired
    private IZEngiineeringPhotoService photoService;

    /**
     * 查询顶管工程
     */
    @Override
    public ZEngineeringPipeJackingVo queryById(String id){
        ZEngineeringPipeJackingVo jackingVo = baseMapper.selectVoById(id);
        ZEngiineeringPhotoBo bo1 = new ZEngiineeringPhotoBo();
        bo1.setParentId(jackingVo.getId());
        bo1.setCreateTime(jackingVo.getCreateTime());
        jackingVo.setPics(photoService.queryList(bo1));
        ZEngineeringNodeBo bo = new ZEngineeringNodeBo();
        bo.setCreateTime(jackingVo.getCreateTime());
        bo.setCivliId(jackingVo.getId());
        jackingVo.setZEngineeringNodeBoList(nodeService.queryListDetails(bo));

        return jackingVo;
    }
    /**
     * 查询顶管工程
     */
    @Override
    public ZEngineeringPipeJackingVo queryByIdType(String id,String type){
        ZEngineeringPipeJackingVo jackingVo = baseMapper.selectVoById(id);

        ZEngiineeringPhotoBo bo1 = new ZEngiineeringPhotoBo();
        bo1.setParentId(jackingVo.getId());
        bo1.setCreateTime(jackingVo.getCreateTime());
        jackingVo.setPics(photoService.queryList(bo1));


        ZEngineeringNodeBo bo = new ZEngineeringNodeBo();
        bo.setCreateTime(jackingVo.getCreateTime());
        bo.setCivliId(jackingVo.getId());
        bo.setType(type);
        jackingVo.setZEngineeringNodeBo(nodeService.query(bo));
        return jackingVo;
    }

    @Override
    public List<Map<String, Object>> nameList(ZEngineeringPipeJackingBo bo) {
        return baseMapper.nameList(bo);
    }

    /**
     * 查询顶管工程列表
     */
    @Override
    public TableDataInfo<ZEngineeringPipeJackingVo> queryPageList(ZEngineeringPipeJackingBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ZEngineeringPipeJacking> lqw = buildQueryWrapper(bo);
        Page<ZEngineeringPipeJackingVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        Map<String, Object> ReviewList = nodeService.ReViewPipeJackingList(result.getRecords());
        result.getRecords().forEach(item -> {
            item.setNodeReViewStateList(ReviewList.get(item.getId()));
        });
        return TableDataInfo.build(result);
    }

    /**
     * 查询顶管工程列表
     */
    @Override
    public List<ZEngineeringPipeJackingVo> queryList(ZEngineeringPipeJackingBo bo) {
        LambdaQueryWrapper<ZEngineeringPipeJacking> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ZEngineeringPipeJacking> buildQueryWrapper(ZEngineeringPipeJackingBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ZEngineeringPipeJacking> lqw = Wrappers.lambdaQuery();
        lqw.orderByDesc(ZEngineeringPipeJacking::getCreateTime);
        lqw.like(StringUtils.isNotBlank(bo.getEnginId()), ZEngineeringPipeJacking::getEnginId, bo.getEnginId());
        lqw.like(StringUtils.isNotBlank(bo.getEnginName()), ZEngineeringPipeJacking::getEnginName, bo.getEnginName());
        lqw.eq(StringUtils.isNotBlank(bo.getEnginAddre()), ZEngineeringPipeJacking::getEnginAddre, bo.getEnginAddre());
        lqw.eq(StringUtils.isNotBlank(bo.getEnginCode()), ZEngineeringPipeJacking::getEnginCode, bo.getEnginCode());
        lqw.eq(StringUtils.isNotBlank(bo.getConstructUnit()), ZEngineeringPipeJacking::getConstructUnit, bo.getConstructUnit());
        lqw.eq(StringUtils.isNotBlank(bo.getEnginScale()), ZEngineeringPipeJacking::getEnginScale, bo.getEnginScale());
        lqw.eq(StringUtils.isNotBlank(bo.getConstructQuality()), ZEngineeringPipeJacking::getConstructQuality, bo.getConstructQuality());
        lqw.eq(StringUtils.isNotBlank(bo.getConstructSchedule()), ZEngineeringPipeJacking::getConstructSchedule, bo.getConstructSchedule());
        return lqw;
    }

    /**
     * 新增顶管工程 PC
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public Boolean insertByBo(ZEngineeringPipeJackingBo bo) {
        ZEngineeringPipeJacking add = BeanUtil.toBean(bo, ZEngineeringPipeJacking.class);
        validEntityBeforeSave(add);
        if (StringUtils.isEmpty(bo.getId())){
            boolean flag = baseMapper.insert(add) > 0;
            if (flag) {
                bo.setId(add.getId());
                List<ZEngiineeringPhoto> list = new ArrayList<>();
                bo.getFiles().forEach(o -> {
                    ZEngiineeringPhoto pic = new ZEngiineeringPhoto();
                    pic.setParentId(bo.getId());
                    pic.setPicUrl(o.getUrl());
                    pic.setFileName(o.getName());
                    pic.setCreateBy(String.valueOf(LoginHelper.getUserId()));
                    pic.setCreateTime(new Date());
                    list.add(pic);
                });
                if (!list.isEmpty()) {
                    photoService.insertBatch(list);
                }
            }
            if (!ObjectUtils.isEmpty(bo.getzEngineeringNodeBo())) {
                bo.getzEngineeringNodeBo().setCivliId(add.getId());
                bo.getzEngineeringNodeBo().setCreateTime(new Date());
                nodeService.insert(bo.getzEngineeringNodeBo());
            }
            return flag;
        }
        else if (StringUtils.isNotBlank(bo.getId())){
            ZEngineeringPipeJackingVo voById = baseMapper.selectVoById(bo.getId());
            List<ZEngineeringNodeBo> zEngineeringNodeBoList = bo.getzEngineeringNodeBoList();
            ZEngineeringNodeBo entity = bo.getzEngineeringNodeBo();
            //pc
            if (!ObjectUtils.isEmpty(zEngineeringNodeBoList)) {
                for (ZEngineeringNodeBo zEngineeringNodeBo : zEngineeringNodeBoList) {
                    zEngineeringNodeBo.setCivliId(voById.getId());
                    zEngineeringNodeBo.setCreateTime(voById.getCreateTime());
                    ZEngineeringNodeBo query = nodeService.query(zEngineeringNodeBo);
                    if (!ObjectUtils.isEmpty(query)) {
                        zEngineeringNodeBo.setId(query.getId());
                    }
                    nodeService.insert(zEngineeringNodeBo);
                }
            }
            //uniapp
            if (!ObjectUtils.isEmpty(entity)) {
                entity.setCivliId(voById.getId());
                entity.setCreateTime(voById.getCreateTime());
                ZEngineeringNodeBo query = nodeService.query(entity);
                if (!ObjectUtils.isEmpty(query)) {
                    entity.setId(query.getId());
                }
                nodeService.insert(entity);
            }
            return true;
        }
        return false;
    }

    @Transactional(rollbackFor=Exception.class)
    @Override
    public Boolean insertByBoApp(ZEngineeringPipeJackingBo bo) {
        ZEngineeringPipeJacking add = BeanUtil.toBean(bo, ZEngineeringPipeJacking.class);
        validEntityBeforeSave(add);

        LambdaQueryWrapper<ZEngineeringPipeJacking> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getId()), ZEngineeringPipeJacking::getId, bo.getId());
        ZEngineeringPipeJackingVo jackingVo = baseMapper.selectVoOne(lqw);
                ZEngineeringNodeBo zEngineeringNodeBo = bo.getzEngineeringNodeBo();
                zEngineeringNodeBo.setCivliId(jackingVo.getId());
                zEngineeringNodeBo.setType(zEngineeringNodeBo.getType());
                zEngineeringNodeBo.setCreateTime(jackingVo.getCreateTime());
                ZEngineeringNodeBo query = nodeService.query(zEngineeringNodeBo);
                if (!ObjectUtils.isEmpty(query)) {
                    zEngineeringNodeBo.setId(query.getId());
                }
                nodeService.insert(bo.getzEngineeringNodeBo());

        return true;
    }


    /**
     * 修改顶管工程 PC
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public Boolean updateByBo(ZEngineeringPipeJackingBo bo) {
        LambdaQueryWrapper<ZEngineeringPipeJacking> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(StringUtils.isNotEmpty(bo.getEnginName()),ZEngineeringPipeJacking::getEnginName,bo.getEnginName())
                .ne(StringUtils.isNotEmpty(bo.getId()),ZEngineeringPipeJacking::getId,bo.getId());
        List<ZEngineeringPipeJacking> zEngineeringPipeJackings = baseMapper.selectList(wrapper);
        if (zEngineeringPipeJackings.size() > 0){
            return false;
        }
        ZEngineeringPipeJacking update = BeanUtil.toBean(bo, ZEngineeringPipeJacking.class);
        validEntityBeforeSave(update);
        int i = baseMapper.updateById(update);
        if (i>0){
            ZEngineeringPipeJackingVo jackingVo = baseMapper.selectVoById(update.getId());
            ZEngineeringNodeBo zEngineeringNodeBo = bo.getzEngineeringNodeBo();
            if (!ObjectUtils.isEmpty(zEngineeringNodeBo)){
                //多info
                if (zEngineeringNodeBo.getzEngineeringInfoBoList()!=null&&!zEngineeringNodeBo.getzEngineeringInfoBoList().isEmpty()){
                    List<ZEngineeringInfoBo> engineeringInfoBoList = zEngineeringNodeBo.getzEngineeringInfoBoList();
                    if (engineeringInfoBoList != null && !engineeringInfoBoList.isEmpty()) {
                        nodeService.updateMuch(zEngineeringNodeBo);
                    }
                }
                //单info
                if (!ObjectUtil.isEmpty(zEngineeringNodeBo.getzEngineeringInfoBo())) {
                    zEngineeringNodeBo.setCivliId(jackingVo.getId());
                    zEngineeringNodeBo.setCreateTime(jackingVo.getCreateTime());
                    nodeService.update(zEngineeringNodeBo);
                }
            }
            if (bo.getFiles()!=null&&!bo.getFiles().isEmpty()) {
                this.doPhotos(update,bo);
            }
        }
        return i>0;
    }

    private void doPhotos(ZEngineeringPipeJacking update,ZEngineeringPipeJackingBo bo) {
        List<ZEngiineeringPhoto> list = new ArrayList<>();

        // 查询数据库中已存在的文件列表
        ZEngiineeringPhotoBo bo1 = new ZEngiineeringPhotoBo();
        bo1.setParentId(update.getId());
        bo1.setCreateTime(update.getCreateTime());
        List<ZEngiineeringPhotoVo> queriedList = photoService.queryList(bo1);
        List<String> existingPhotos = queriedList.stream()
            .map(ZEngiineeringPhotoVo::getPicUrl)
            .collect(Collectors.toList());

        // 插入前端传来的新文件
        for (ZFileBo pic : bo.getFiles()) {
            if (!existingPhotos.contains(pic.getUrl())) {
                ZEngiineeringPhoto newPhoto = new ZEngiineeringPhoto();
                newPhoto.setParentId(bo.getId());
                newPhoto.setPicUrl(pic.getUrl());
                newPhoto.setFileName(pic.getName());
                newPhoto.setCreateBy(String.valueOf(LoginHelper.getUsername()));
                newPhoto.setUpdateBy(String.valueOf(LoginHelper.getUsername()));
                newPhoto.setCreateTime(bo.getCreateTime());
                newPhoto.setUpdateTime(new Date());
                list.add(newPhoto);
            }
        }

        // 删除数据库中多余的文件
        List<String> photosToDelete = existingPhotos.stream()
            .filter(pic -> !bo.getFiles().stream().map(ZFileBo::getUrl).collect(Collectors.toList()).contains(pic))
            .collect(Collectors.toList());
        if (!photosToDelete.isEmpty()) {
            photosToDelete.forEach(item->{
                ZEngiineeringPhoto zEngiineeringPhoto=new ZEngiineeringPhoto();
                zEngiineeringPhoto.setPicUrl(item);
                zEngiineeringPhoto.setCreateTime(bo.getCreateTime());
                photoService.deleteWithValid(zEngiineeringPhoto);
            });
        }

        // 批量插入新图片
        if (!list.isEmpty()) {
            photoService.insertBatch(list);
        }
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ZEngineeringPipeJacking entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除顶管工程
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        //TODO 做一些业务上的校验,判断是否需要校验
        ids.forEach(item -> {
            ZEngineeringPipeJackingVo vo = baseMapper.selectVoById(item);
            ZEngineeringNodeBo zEngineeringNodeBo = new ZEngineeringNodeBo();
            zEngineeringNodeBo.setCreateTime(vo.getCreateTime());
            zEngineeringNodeBo.setCivliId(vo.getId());
            List<ZEngineeringNodeBo> zEngineeringNodeBos = nodeService.queryListDetails(zEngineeringNodeBo);
            zEngineeringNodeBos.forEach(ite ->
                nodeService.delete(ite)
            );
        });
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
