package com.ruoyi.zdsz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.DynamicName;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.handler.MonthTableNameHandler;
import com.ruoyi.framework.obs.ObsService;
import com.ruoyi.zdsz.domain.ZEngiineeringPhoto;
import com.ruoyi.zdsz.domain.ZEngineeringInfo;
import com.ruoyi.zdsz.domain.bo.ZEngiineeringPhotoBo;
import com.ruoyi.zdsz.domain.bo.ZEngineeringCivilBo;
import com.ruoyi.zdsz.domain.bo.ZEngineeringInfoBo;
import com.ruoyi.zdsz.domain.bo.ZEngineeringPipeJackingBo;
import com.ruoyi.zdsz.domain.vo.ZEngiineeringPhotoVo;
import com.ruoyi.zdsz.mapper.ZEngiineeringPhotoMapper;
import com.ruoyi.zdsz.service.IZEngiineeringPhotoService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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 2023-12-27
 */
@RequiredArgsConstructor
@Service
public class ZEngiineeringPhotoServiceImpl implements IZEngiineeringPhotoService {
    @Value("${filePath}")
    private String filePath;

    private final ZEngiineeringPhotoMapper baseMapper;
    @Resource
    private ObsService obsService;

    /**
     * 查询照片
     */
    @Override
    public ZEngiineeringPhotoVo queryById(String id) {
        return baseMapper.selectVoById(id);
    }

    @Override
    @DynamicName(spel = "#bo.createTime")
//    @Async("threadPoolTaskExecutor")
    public List<String> queryList(ZEngineeringInfoBo bo) {
        List<String> list = new ArrayList<>();
        LambdaQueryWrapper<ZEngiineeringPhoto> lqw = Wrappers.lambdaQuery();
        lqw.orderByDesc(ZEngiineeringPhoto::getUpdateTime);
        lqw.isNull(ZEngiineeringPhoto::getType);
        lqw.eq(StringUtils.isNotBlank(bo.getId()), ZEngiineeringPhoto::getParentId, bo.getId()).orderByDesc(ZEngiineeringPhoto::getCreateTime);
        List<ZEngiineeringPhoto> zEngiineeringPhotoList = baseMapper.selectList(lqw);
        zEngiineeringPhotoList.stream().forEach(item -> {
            list.add(item.getPicUrl());
        });
        return list;
    }
    @Override
    @DynamicName(spel = "#bo.createTime")
//    @Async("threadPoolTaskExecutor")
    public List<String> queryInsertList(ZEngineeringInfoBo bo) {
        List<String> list = new ArrayList<>();
        LambdaQueryWrapper<ZEngiineeringPhoto> lqw = Wrappers.lambdaQuery();
        lqw.orderByDesc(ZEngiineeringPhoto::getUpdateTime);
        //lqw.isNull(ZEngiineeringPhoto::getType);
        lqw.eq(StringUtils.isNotBlank(bo.getId()), ZEngiineeringPhoto::getParentId, bo.getId()).orderByDesc(ZEngiineeringPhoto::getCreateTime);
        List<ZEngiineeringPhoto> zEngiineeringPhotoList = baseMapper.selectList(lqw);
        zEngiineeringPhotoList.stream().forEach(item -> {
            list.add(item.getPicUrl());
        });
        return list;
    }

    @Override
    @DynamicName(spel = "#bo.createTime")
    public List<String> queryTypeList(ZEngineeringInfoBo bo,String Type) {
        List<String> list = new ArrayList<>();
        LambdaQueryWrapper<ZEngiineeringPhoto> lqw = Wrappers.lambdaQuery();
        lqw.orderByDesc(ZEngiineeringPhoto::getUpdateTime);
        lqw.eq(StringUtils.isNotBlank(Type), ZEngiineeringPhoto::getType, Type);
        lqw.eq(StringUtils.isNotBlank(bo.getId()), ZEngiineeringPhoto::getParentId, bo.getId()).orderByDesc(ZEngiineeringPhoto::getCreateTime);
        List<ZEngiineeringPhoto> zEngiineeringPhotoList = baseMapper.selectList(lqw);
        zEngiineeringPhotoList.stream().forEach(item -> {
            list.add(item.getPicUrl());
        });
        return list;
    }

    /**
     * 查询照片列表
     */
    @Override
    public TableDataInfo<ZEngiineeringPhotoVo> queryPageList(ZEngiineeringPhotoBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ZEngiineeringPhoto> lqw = buildQueryWrapper(bo);
        Page<ZEngiineeringPhotoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询照片列表
     */
    @Override
    @DynamicName(spel = "#bo.createTime")
    public List<ZEngiineeringPhotoVo> queryList(ZEngiineeringPhotoBo bo) {
        LambdaQueryWrapper<ZEngiineeringPhoto> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ZEngiineeringPhoto> buildQueryWrapper(ZEngiineeringPhotoBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ZEngiineeringPhoto> lqw = Wrappers.lambdaQuery();
        lqw.orderByDesc(ZEngiineeringPhoto::getUpdateTime);
        lqw.eq(StringUtils.isNotBlank(bo.getParentId()), ZEngiineeringPhoto::getParentId, bo.getParentId());
        lqw.eq(StringUtils.isNotBlank(bo.getPicUrl()), ZEngiineeringPhoto::getPicUrl, bo.getPicUrl());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), ZEngiineeringPhoto::getType, bo.getType());
        return lqw;
    }

    /**
     * 新增照片
     */
    @Override
    public Boolean insertByBo(ZEngiineeringPhotoBo bo) {
        ZEngiineeringPhoto add = BeanUtil.toBean(bo, ZEngiineeringPhoto.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 批量插入
     *
     * @param bo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @DynamicName(spel = "#bo[0].createTime")
//    @Async("threadPoolTaskExecutor")
    public Boolean insertBatch(List<ZEngiineeringPhoto> bo) {
        boolean flag = baseMapper.insertBatch(bo);
        return flag;
    }

    /**
     * 修改照片
     */
    @Override
    public Boolean updateByBo(ZEngiineeringPhotoBo bo) {
        ZEngiineeringPhoto update = BeanUtil.toBean(bo, ZEngiineeringPhoto.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    @Override
    @DynamicName(spel = "#bo[0].createTime")
    @Transactional(rollbackFor = Exception.class)
//    @Async("threadPoolTaskExecutor")
    public Boolean updateBatch(List<ZEngiineeringPhoto> bo) {
        ZEngiineeringPhoto zEngiineeringPhoto = bo.get(0);
        LambdaQueryWrapper<ZEngiineeringPhoto> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(zEngiineeringPhoto.getParentId()), ZEngiineeringPhoto::getParentId, zEngiineeringPhoto.getParentId());
        List<ZEngiineeringPhoto> zEngiineeringPhotoList = baseMapper.selectList(lqw);
        List<String> list = new ArrayList<>();
        zEngiineeringPhotoList.stream().forEach(item -> {
            list.add(item.getPicUrl());
        });
        List<String> bolist = new ArrayList<>();
        bo.stream().forEach(item -> {
            bolist.add(item.getPicUrl());
        });
        List dlList = list.stream().filter(i -> !bolist.contains(i)).collect(Collectors.toList());
        List<String> inList = bolist.stream().filter(i -> !list.contains(i)).collect(Collectors.toList());
        obsService.deleteFiles(dlList);
        List dlIdList = new ArrayList();
        dlList.stream().forEach(item -> {
            zEngiineeringPhotoList.stream().forEach(Photoitem -> {
                if (Photoitem.getPicUrl() == item) {
                    dlIdList.add(Photoitem);
                }
            });

        });
        if (dlIdList.size() != 0) {
            baseMapper.deleteBatchIds(dlIdList);

        }
        if (inList.size() != 0) {
            List<ZEngiineeringPhoto> photoList = new ArrayList();
            inList.stream().forEach(item -> {
                ZEngiineeringPhoto zEngiineeringPhoto1 = new ZEngiineeringPhoto();
                zEngiineeringPhoto1.setParentId(zEngiineeringPhoto.getParentId());
                zEngiineeringPhoto1.setPicUrl(item);
                zEngiineeringPhoto1.setUpdateTime(new Date());
                zEngiineeringPhoto1.setCreateTime(zEngiineeringPhoto.getCreateTime());
                zEngiineeringPhoto1.setType(bo.stream().filter(i->i.getPicUrl()==item).collect(Collectors.toList()).get(0).getType());
                photoList.add(zEngiineeringPhoto1);
            });
            insertBatch(photoList);
        }
        return null;


    }

    @Override
    @DynamicName(spel = "#bo.createTime")
    @Transactional(rollbackFor = Exception.class)
//    @Async("threadPoolTaskExecutor")
    public Boolean delete(ZEngineeringInfoBo bo) {
        LambdaQueryWrapper<ZEngiineeringPhoto> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getId()), ZEngiineeringPhoto::getParentId, bo.getId());
        List<ZEngiineeringPhoto> zEngiineeringPhoto = baseMapper.selectList(lqw);
        List IdList = new ArrayList();
        List UrlList = new ArrayList();
        zEngiineeringPhoto.stream().forEach(item -> {
            IdList.add(item.getId());
            UrlList.add(item.getPicUrl());

        });
        int flag = 0;
        if (IdList.size() > 0) {
            obsService.deleteFiles(UrlList);
            flag = baseMapper.deleteBatchIds(IdList);
        }
        ;
        return flag > 0;
    }
    @Override
    @DynamicName(spel = "#bo.createTime")
    @Transactional(rollbackFor = Exception.class)
//    @Async("threadPoolTaskExecutor")
    public Boolean deleteNodelFiles(ZEngineeringInfoBo bo) {
        LambdaQueryWrapper<ZEngiineeringPhoto> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getId()), ZEngiineeringPhoto::getParentId, bo.getId());
        List<ZEngiineeringPhoto> zEngiineeringPhoto = baseMapper.selectList(lqw);
        List IdList = new ArrayList();
        List UrlList = new ArrayList();
        zEngiineeringPhoto.stream().forEach(item -> {
            IdList.add(item.getId());
            UrlList.add(item.getPicUrl());

        });
        int flag = 0;
        if (IdList.size() > 0) {
           // obsService.deleteFiles(UrlList);
            flag = baseMapper.deleteBatchIds(IdList);
        }
        ;
        return flag > 0;
    }

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

    /**
     * 批量删除照片
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 删除照片
     */
    @Override
    public Boolean deleteWithValidByurls(String url) {
        try {
            obsService.deleteFiles(Collections.singletonList(url));
        } catch (Exception e) {

        }
        return baseMapper.deleteByUrls(url) > 0;
    }

    @Override
    @DynamicName(spel = "#bo.createTime")
    public Boolean deleteWithValid(ZEngiineeringPhoto bo) {
        try {
            obsService.deleteFiles(Collections.singletonList(bo.getPicUrl()));
        } catch (Exception e) {

        }
        return baseMapper.deleteByUrls(bo.getPicUrl()) > 0;
    }

    @Override
    @DynamicName(spel = "#bo.createTime")
    @Async
    public void writeImg(List<ZEngineeringInfoBo> infoIdList,ZEngineeringInfoBo bo,String engInfoName) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy_MM");
        MonthTableNameHandler.setData(format.format(bo.getCreateTime()));
        Map<String, String> objInfo = baseMapper.getObjInfo(bo.getEngInfoId());
        MonthTableNameHandler.removeData();
        infoIdList.forEach(item -> {
            item.getzEngiineeringPhotoBoList().forEach(photo -> {
                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[] typeFileNameBytes = (file.getPath() + "/" + objInfo.get("type")).getBytes("UTF-8");
                        // 使用UTF-8编码创建文件
                        File typeFile = new File(new String(typeFileNameBytes, "UTF-8"));
                        if (!typeFile.exists()) {
                            typeFile.mkdirs();
                        }
                        // 第二程文件夹名称（工程名称）
                        byte[] enginNameFileNameBytes = (typeFile.getPath() + "/" + objInfo.get("engin_name")).getBytes("UTF-8");
                        // 使用UTF-8编码创建文件
                        File enginNameFile = new File(new String(enginNameFileNameBytes, "UTF-8"));
                        if (!enginNameFile.exists()) {
                            enginNameFile.mkdirs();
                        }
                        //节点
                        byte[] TypeNameBytes = (enginNameFile.getPath() + "/" + engInfoName).getBytes("UTF-8");
                        // 使用UTF-8编码创建文件
                        File Type = new File(new String(TypeNameBytes, "UTF-8"));
                        if (!Type.exists()) {
                            Type.mkdirs();
                        }

                        // 时间
                        byte[] CreateTimeFileNameBytes = (Type.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();
                        }
                        // 人名
                        byte[] CreateByFileNameBytes = (CreateTimeFile.getPath() + "/" + item.getConstructUser()).getBytes("UTF-8");
                        // 使用UTF-8编码创建文件
                        File CreateByFile = new File(new String(CreateByFileNameBytes, "UTF-8"));
                        if (!CreateByFile.exists()) {
                            CreateByFile.mkdirs();
                        }
                        obsService.download(CreateByFile.getPath(), photo.substring(photo.lastIndexOf("/")+1));
                        System.out.println(photo.substring(photo.lastIndexOf("/")+1));
                        System.out.println(photo);
                        System.out.println(CreateByFile.getPath());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }


                }
            });
        });
    }

    @Override
    @Async
    public void write(ZEngineeringCivilBo zEngineeringCivilBo) {
        zEngineeringCivilBo.getzEngineeringNodeBo().getzEngineeringInfoBoList().forEach(zEngineeringInfoBo -> {
                zEngineeringInfoBo.getzEngiineeringPhotoBoList().forEach(photo -> {
                    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();
                        }
//                        // 创建行政区
//                        File headFile = new File(file.getPath() + "/" + zEngineeringCivilBo.getDistrict());
//                        if (!headFile.exists()) {
//                            headFile.mkdirs();
//                        }
                        // 小区下再次创建小区，本级用于导出
//                        File areaFile = new File(file.getPath() + "/" + zEngineeringCivilBo.getAreaId());
                        byte[] areafileNameBytes = (file.getPath() + "/" + zEngineeringCivilBo.getAreaId()).getBytes("UTF-8");
                        // 使用UTF-8编码创建文件
                        File areaFile = new File(new String(areafileNameBytes, "UTF-8"));
                        if (!areaFile.exists()) {
                            areaFile.mkdirs();
                        }
                        // 楼
//                        File buildingFile = new File(areaFile.getPath() + "/" + zEngineeringCivilBo.getBuildingId());
                        byte[] buildingfileNameBytes = (areaFile.getPath() + "/" + zEngineeringCivilBo.getBuildingId()).getBytes("UTF-8");
                        // 使用UTF-8编码创建文件
                        File buildingFile = new File(new String(buildingfileNameBytes, "UTF-8"));
                        if (!buildingFile.exists()) {
                            buildingFile.mkdirs();
                        }
                        // 单元
//                        File unitFile = new File(buildingFile.getPath() + "/" + zEngineeringCivilBo.getUnitId());
                        byte[] unitfileNameBytes = (buildingFile.getPath() + "/" + zEngineeringCivilBo.getUnitId()).getBytes("UTF-8");
                        // 使用UTF-8编码创建文件
                        File unitFile = new File(new String(unitfileNameBytes, "UTF-8"));
                        if (!unitFile.exists()) {
                            unitFile.mkdirs();
                        }
                        // 房间
//                        File houseFile = new File(unitFile.getPath() + "/" + zEngineeringCivilBo.getHouseId());
                        byte[] housefileNameBytes = (unitFile.getPath() + "/" + zEngineeringCivilBo.getHouseId()).getBytes("UTF-8");
                        // 使用UTF-8编码创建文件
                        File houseFile = new File(new String(housefileNameBytes, "UTF-8"));
                        if (!houseFile.exists()) {
                            houseFile.mkdirs();
                        }
                        // 工程周期
//                        File EnginCycleFile = new File(houseFile.getPath() + "/" + zEngineeringCivilBo.getEnginCycle());
                            byte[] EnginCycleNameBytes = (houseFile.getPath() + "/" + zEngineeringCivilBo.getEnginCycle()).getBytes("UTF-8");
                            // 使用UTF-8编码创建文件
                            File EnginCycleFile = new File(new String(EnginCycleNameBytes, "UTF-8"));
                        if (!EnginCycleFile.exists()) {
                            EnginCycleFile.mkdirs();
                        }
                        // 工程类型
//                        File EnginType = new File(EnginCycleFile.getPath() + "/" + zEngineeringCivilBo.getEnginType());
                            byte[] EnginTypeNameBytes = (EnginCycleFile.getPath() + "/" + zEngineeringCivilBo.getEnginType()).getBytes("UTF-8");
                            // 使用UTF-8编码创建文件
                            File EnginType = new File(new String(EnginTypeNameBytes, "UTF-8"));
                        if (!EnginType.exists()) {
                            EnginType.mkdirs();
                        }
                        // 工程分类
//                        File EnginClassification = new File(EnginType.getPath() + "/" + zEngineeringCivilBo.getEnginClassification());
                            byte[] EnginClassificationNameBytes = (EnginType.getPath() + "/" + zEngineeringCivilBo.getEnginClassification()).getBytes("UTF-8");
                            // 使用UTF-8编码创建文件
                            File EnginClassification = new File(new String(EnginClassificationNameBytes, "UTF-8"));
                        if (!EnginClassification.exists()) {
                            EnginClassification.mkdirs();
                        }
                        // 节点类型
//                        File Type = new File(EnginClassification.getPath() + "/" + zEngineeringCivilBo.getzEngineeringNodeBo().getType());
                            byte[] TypeNameBytes = (EnginClassification.getPath() + "/" + zEngineeringCivilBo.getzEngineeringNodeBo().getType()).getBytes("UTF-8");
                            // 使用UTF-8编码创建文件
                            File Type = new File(new String(TypeNameBytes, "UTF-8"));
                        if (!Type.exists()) {
                            Type.mkdirs();
                        }
                        // 时间
//                        File CreateTimeFile = new File(Type.getPath() + "/" + new SimpleDateFormat("yyyy-MM-dd").format(zEngineeringInfoBo.getCreateTime()) );
                            byte[] CreateTimeFileNameBytes = (Type.getPath() + "/" + new SimpleDateFormat("yyyy-MM-dd").format(zEngineeringInfoBo.getCreateTime())).getBytes("UTF-8");
                            // 使用UTF-8编码创建文件
                            File CreateTimeFile = new File(new String(CreateTimeFileNameBytes, "UTF-8"));
                        if (!CreateTimeFile.exists()) {
                            CreateTimeFile.mkdirs();
                        }
//                        File CreateByFile = new File(CreateTimeFile.getPath() + "/" + zEngineeringInfoBo.getConstructUser());
                            byte[] CreateByFileNameBytes = (CreateTimeFile.getPath() + "/" + zEngineeringInfoBo.getConstructUser()).getBytes("UTF-8");
                            // 使用UTF-8编码创建文件
                            File CreateByFile = new File(new String(CreateByFileNameBytes, "UTF-8"));
                        if (!CreateByFile.exists()) {
                            CreateByFile.mkdirs();
                        }
                            obsService.download(CreateByFile.getPath(), photo.substring(photo.lastIndexOf("/")+1));
                            System.out.println(photo.substring(photo.lastIndexOf("/")+1));
                            System.out.println(photo);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }


                    }

                });

            });
    }
}
