package com.ruoyi.zdsz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.annotation.DynamicName;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.DateUtils;
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.ZEngineeringInfo;
import com.ruoyi.zdsz.domain.ZEngineeringNode;
import com.ruoyi.zdsz.domain.bo.*;
import com.ruoyi.zdsz.domain.vo.ZEngiineeringPhotoVo;
import com.ruoyi.zdsz.domain.vo.ZEngineeringIndustryVo;
import com.ruoyi.zdsz.domain.vo.ZEngineeringPipeJackingVo;
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.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.ruoyi.zdsz.domain.vo.ZEngineeringDangerousVo;
import com.ruoyi.zdsz.domain.ZEngineeringDangerous;
import com.ruoyi.zdsz.mapper.ZEngineeringDangerousMapper;
import com.ruoyi.zdsz.service.IZEngineeringDangerousService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 危险工程Service业务层处理
 *
 * @author ruoyi
 * @date 2024-01-02
 */
@RequiredArgsConstructor
@Service
public class ZEngineeringDangerousServiceImpl implements IZEngineeringDangerousService {

    private final ZEngineeringDangerousMapper baseMapper;

    @Autowired
    private IZEngineeringNodeService izEngineeringNodeService;

    @Autowired
    private IZEngiineeringPhotoService photoService;
    @Value("${filePath}")
    private String filePath;
    @Resource
    private ObsService obsService;
    @Override
    public boolean review(ZEngineeringDangerousBo zEngineeringDangerousBo) {
        System.out.println(zEngineeringDangerousBo);
        ZEngineeringDangerous add = BeanUtil.toBean(zEngineeringDangerousBo, ZEngineeringDangerous.class);
        int i = baseMapper.updateById(add);
        if ("1".equals(zEngineeringDangerousBo.getReviewStatus())){
            ZEngiineeringPhotoBo bo = new ZEngiineeringPhotoBo();
            bo.setParentId(add.getId());
            bo.setCreateTime(zEngineeringDangerousBo.getCreateTime());
            write(photoService.queryList(bo), add.getEnginName());
        }
        return i>0;
    }

    @Async
    public void write(List<ZEngiineeringPhotoVo> zEngiineeringPhotoVos,String enginName) {
        zEngiineeringPhotoVos.forEach( item ->{
            String photo = item.getPicUrl();
            if (StringUtils.isNotBlank(photo)) {
                try {
                    // 创建最外层文件夹
                    byte[] fileNameBytes = filePath.getBytes("UTF-8");
                    // 使用UTF-8编码创建文件
                    File file = new File(new String(fileNameBytes, "UTF-8"));
                    if (!file.exists()) {
                        file.mkdirs();
                    }
                    byte[] typeFileNameByte = (file.getPath() + "/危险工程").getBytes("UTF-8");
                    // 使用UTF-8编码创建文件
                    File typeFiles = new File(new String(typeFileNameByte, "UTF-8"));
                    if (!typeFiles.exists()) {
                        typeFiles.mkdirs();
                    }
                    byte[] typeFileNameBytes = (typeFiles.getPath() + "/" + enginName).getBytes("UTF-8");
                    // 使用UTF-8编码创建文件
                    File typeFile = new File(new String(typeFileNameBytes, "UTF-8"));
                    if (!typeFile.exists()) {
                        typeFile.mkdirs();
                    }
                    byte[] enginNameFileNameBytes = (typeFile.getPath() + "/" + baseMapper.getName(item.getCreateBy())).getBytes("UTF-8");
                    // 使用UTF-8编码创建文件
                    File enginNameFile = new File(new String(enginNameFileNameBytes, "UTF-8"));
                    if (!enginNameFile.exists()) {
                        enginNameFile.mkdirs();
                    }
                    byte[] CreateTimeFileNameBytes = (enginNameFile.getPath() + "/" + new SimpleDateFormat("yyyy-MM-dd").format(item.getUpdateTime())).getBytes("UTF-8");
                    // 时间
                    // 使用UTF-8编码创建文件
                    File CreateTimeFile = new File(new String(CreateTimeFileNameBytes, "UTF-8"));
                    if (!CreateTimeFile.exists()) {
                        CreateTimeFile.mkdirs();
                    }
                    obsService.download(CreateTimeFile.getPath(), photo.substring(photo.lastIndexOf("/")+1));

                } catch (IOException e) {
                    e.printStackTrace();
                }


            }
        });
    }
    /**
     * 查询危险工程列表
     */
    @Override
    public TableDataInfo<ZEngineeringDangerousVo> queryPageList(ZEngineeringDangerousBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ZEngineeringDangerous> lqw = buildQueryWrapper(bo);
        Page<ZEngineeringDangerousVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询危险工程详情
     */
    @Override
    public ZEngineeringDangerousVo query(String id) {
        ZEngineeringDangerousVo vo = baseMapper.selectVoById(id);
        ZEngiineeringPhotoBo bo = new ZEngiineeringPhotoBo();
        bo.setParentId(vo.getId());
        bo.setCreateTime(vo.getCreateTime());
        vo.setPics(photoService.queryList(bo));
        ZEngineeringNodeBo zEngineeringNodeBo = new ZEngineeringNodeBo();
        zEngineeringNodeBo.setCivliId(vo.getId());
        zEngineeringNodeBo.setCreateTime(vo.getCreateTime());
        List<ZEngineeringNodeBo> zEngineeringNodeBos = izEngineeringNodeService.queryListDetails(zEngineeringNodeBo);
        vo.setzEngineeringNodeBoList(zEngineeringNodeBos);
        return vo;
    }

    /**
     * 查询危险工程列表
     */
    @Override
    public List<ZEngineeringDangerousVo> queryList(ZEngineeringDangerousBo bo) {
        LambdaQueryWrapper<ZEngineeringDangerous> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ZEngineeringDangerous> buildQueryWrapper(ZEngineeringDangerousBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ZEngineeringDangerous> lqw = Wrappers.lambdaQuery();
        lqw.orderByDesc(ZEngineeringDangerous::getCreateTime);
        lqw.like(StringUtils.isNotBlank(bo.getBasicInformation()), ZEngineeringDangerous::getBasicInformation, bo.getBasicInformation());
        lqw.like(StringUtils.isNotBlank(bo.getEnginName()), ZEngineeringDangerous::getEnginName, bo.getEnginName());
        lqw.like(StringUtils.isNotBlank(bo.getEnginAddre()), ZEngineeringDangerous::getEnginAddre, bo.getEnginAddre());
        return lqw;
    }


    /**
     * 新增危险工程
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @DynamicName(spel = "#bo.createTime")
    public Boolean insert(ZEngineeringDangerousBo bo) {
        ZEngineeringDangerous add = BeanUtil.toBean(bo, ZEngineeringDangerous.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        bo.getzEngineeringNodeBo().setCivliId(add.getId());
        bo.getzEngineeringNodeBo().setCreateTime(add.getCreateTime());
        ZEngineeringNode entity = izEngineeringNodeService.insert(bo.getzEngineeringNodeBo());
        if (!ObjectUtil.isEmpty(entity)) {
            List<ZEngiineeringPhoto> list = new ArrayList<>();
            if (!ObjectUtils.isEmpty(bo.getFiles())) {
                bo.getFiles().stream().forEach(o -> {
                    ZEngiineeringPhoto pic = new ZEngiineeringPhoto();
                    pic.setParentId(bo.getId());
                    pic.setPicUrl(o.getUrl());
                    pic.setUpdateBy(String.valueOf(LoginHelper.getUsername()));
                    pic.setUpdateTime(new Date());
                    pic.setCreateTime(bo.getCreateTime());
                    list.add(pic);
                });
            }
            if (!list.isEmpty()) {
                photoService.insertBatch(list);
            }
        }
        return flag;
    }


    /**
     * 修改危险工程
     */
    @Override
    @DynamicName(spel = "#bo.createTime")
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(ZEngineeringDangerousBo bo) {
        ZEngineeringDangerous update = BeanUtil.toBean(bo, ZEngineeringDangerous.class);
        validEntityBeforeSave(update);
        ZEngineeringNodeBo zEngineeringNodeBo = bo.getzEngineeringNodeBo();
        zEngineeringNodeBo.setCivliId(update.getId());
        zEngineeringNodeBo.setId(baseMapper.selectIdByCid(zEngineeringNodeBo.getCivliId()));
        zEngineeringNodeBo.setCreateTime(update.getCreateTime());
        izEngineeringNodeService.update(zEngineeringNodeBo);
        int i = baseMapper.updateById(update);
        if (i > 0) {
            List<ZEngiineeringPhoto> list = new ArrayList<>();

            if (!ObjectUtils.isEmpty(bo.getFiles())) {
                // 查询数据库中已存在的文件列表
                ZEngiineeringPhotoBo bo1 = new ZEngiineeringPhotoBo();
                bo1.setParentId(update.getId());
                List<String> existingPhotos = photoService.queryList(bo1).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(update.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(update.getCreateTime());
                        photoService.deleteWithValid(zEngiineeringPhoto);
                    });
                }
            }

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

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

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

    /**
     * 危险工程历史
     */
    @Override
    public ZEngineeringDangerousVo queryEngineeringDangerous(String id) {
        ZEngineeringDangerousVo vo = baseMapper.selectVoById(id);
        ZEngineeringNodeBo zEngineeringNodeBo = new ZEngineeringNodeBo();
        zEngineeringNodeBo.setCreateTime(vo.getCreateTime());
        zEngineeringNodeBo.setCivliId(vo.getId());
        vo.setzEngineeringNodeBoList(izEngineeringNodeService.queryListDetails(zEngineeringNodeBo));
        return vo;
    }


    /**
     * 新增危险工程（无节点）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(ZEngineeringDangerousBo bo) {
        ZEngineeringDangerous add = BeanUtil.toBean(bo, ZEngineeringDangerous.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        if (!ObjectUtils.isEmpty(bo.getFiles())) {
            List<ZEngiineeringPhoto> list = new ArrayList<>();
            bo.getFiles().stream().forEach(o -> {
                ZEngiineeringPhoto pic = new ZEngiineeringPhoto();
                pic.setParentId(add.getId());
                pic.setPicUrl(o.getUrl());
                pic.setFileName(o.getName());
                pic.setCreateBy(String.valueOf(LoginHelper.getUsername()));
                pic.setCreateTime(new Date());
                pic.setUpdateBy(String.valueOf(LoginHelper.getUsername()));
                pic.setUpdateTime(new Date());
                list.add(pic);
            });
            if (!list.isEmpty()) {
                photoService.insertBatch(list);
            }
        }
        return flag;
    }

    /**
     * 修改危险工程（无节点）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(ZEngineeringDangerousBo bo) {
        ZEngineeringDangerous update = BeanUtil.toBean(bo, ZEngineeringDangerous.class);
        validEntityBeforeSave(update);
        int i = baseMapper.updateById(update);
        if (ObjectUtils.isEmpty(bo.getFiles())){
            List<ZFileBo> files = new ArrayList<>();
            for (ZEngiineeringPhotoVo pic : bo.getPics()) {
                ZFileBo zFileBo = new ZFileBo();
                zFileBo.setName(pic.getFileName());
                zFileBo.setUrl(pic.getPicUrl());
                files.add(zFileBo);
            }
            bo.setFiles(files);
        }
        if (!ObjectUtils.isEmpty(bo.getFiles())) {
            ZEngineeringDangerousVo queryById = this.queryById(bo.getId());
            List<ZEngiineeringPhoto> list = new ArrayList<>();

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

            // 插入前端传来的新文件
            for (ZFileBo pic : bo.getFiles()) {
                if (!existingPhotos.contains(pic.getUrl())) {
                    ZEngiineeringPhoto newPhoto = new ZEngiineeringPhoto();
                    newPhoto.setParentId(update.getId());
                    newPhoto.setPicUrl(pic.getUrl());
                    newPhoto.setFileName(pic.getName());
                    newPhoto.setCreateBy(String.valueOf(LoginHelper.getUsername()));
                    newPhoto.setUpdateBy(String.valueOf(LoginHelper.getUsername()));
                    newPhoto.setCreateTime(queryById.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);
            }
        }
        return i > 0;
    }

    /**
     * 查询危险工程（无节点）
     */
    @Override
    public ZEngineeringDangerousVo queryById(String id) {
        ZEngineeringDangerousVo vo = baseMapper.selectVoById(id);
        ZEngiineeringPhotoBo bo = new ZEngiineeringPhotoBo();
        bo.setParentId(vo.getId());
        bo.setCreateTime(vo.getCreateTime());
        List<ZEngiineeringPhotoVo> zEngiineeringPhotoVos = photoService.queryList(bo);
        zEngiineeringPhotoVos.forEach(item -> item.setCreateByName(baseMapper.getName(item.getCreateBy())));
        vo.setPics(zEngiineeringPhotoVos);
        return vo;
    }
    @Override
    public List<Map<String, Object>> selectEnginNameAndId(ZEngineeringDangerousBo bo) {
        LambdaQueryWrapper<ZEngineeringDangerous> lqw = buildQueryWrapper(bo);
        List<ZEngineeringDangerousVo> zEngineeringDangerousVos = baseMapper.selectVoList(lqw);
        List<Map<String, Object>> filteredList = zEngineeringDangerousVos.stream()
            .map(vo -> {
                Map<String, Object> map = new HashMap<>();
                map.put("name", vo.getEnginName());
                map.put("id", vo.getId());
                return map;
            })
            .collect(Collectors.toList());
        return filteredList;
    }
}
