package com.ruoyi.system.service.impl;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.system.mapper.InvestigateDispositionMapper;
import com.ruoyi.system.mapper.InvestigateDispositionTableMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.domain.entity.InvestigateDisposition;
import com.ruoyi.system.service.IInvestigateDispositionService;
import org.springframework.web.multipart.MultipartFile;

import static com.ruoyi.common.config.RuoYiConfig.getProfile;

/**
 * 考察配置Service业务层处理
 *
 * @author ruoyi
 * @date 2023-10-10
 */
@Service
public class InvestigateDispositionServiceImpl implements IInvestigateDispositionService {
    @Autowired
    private InvestigateDispositionMapper investigateDispositionMapper;

    /**
     * 查询考察配置
     *
     * @param investigateDispositionId 考察配置主键
     * @return 考察配置
     */
    @Override
    public InvestigateDisposition selectInvestigateDispositionByInvestigateDispositionId(Long investigateDispositionId) {
        return investigateDispositionMapper.selectInvestigateDispositionByInvestigateDispositionId(investigateDispositionId);
    }

    /**
     * 查询考察配置列表
     *
     * @param investigateDisposition 考察配置
     * @return 考察配置
     */
    @Override
    public List<InvestigateDisposition> selectInvestigateDispositionList(InvestigateDisposition investigateDisposition) {
        return investigateDispositionMapper.selectInvestigateDispositionList(investigateDisposition);
    }

    /**
     * 新增考察配置
     *
     * @param investigateDisposition 考察配置
     * @return 结果
     */
    @Override
    public int insertInvestigateDisposition(InvestigateDisposition investigateDisposition) {
        String fileName = getFileName(investigateDisposition);
        investigateDisposition.setUrl(fileName);
        InvestigateDisposition info = investigateDispositionMapper.selectInvestigateDispositionById(investigateDisposition.getParentId());
        investigateDisposition.setCreateTime(DateUtils.getNowDate());
        investigateDisposition.setAncestors("0");
        if (info != null) {
            investigateDisposition.setAncestors(info.getAncestors() + "," + investigateDisposition.getParentId());
        }
        return investigateDispositionMapper.insertInvestigateDisposition(investigateDisposition);
    }

    private String getFileName(InvestigateDisposition investigateDisposition) {
        //获取HTML文件
        String content = investigateDisposition.getContent();
        content = " <meta charset=\"utf-8\">\n" +
                "<style>\n" +
                " body{margin: 0 !important;}\n" +
                "img{max-width: 100% !important;height: auto !important;}\n" +
                "</style>" + content;
        String fileName = "";
        try {
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadPath();
            String fileNameHtml = UUID.randomUUID().toString();
            File html = File.createTempFile(fileNameHtml, ".html", new File(filePath));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(html, true), StandardCharsets.UTF_8));
            writer.write(content);
            writer.close();
            InputStream inputStream = new FileInputStream(html);
            MultipartFile file = new org.springframework.mock.web.MockMultipartFile(html.getName(), html.getName(), "text/html", inputStream);
            // 上传并返回新文件名称
            fileName = FileUploadUtils.upload(filePath, file);
            html.delete();
            System.out.println("文件生成成功！");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileName;
    }


    /**
     * 修改考察配置
     *
     * @param investigateDisposition 考察配置
     * @return 结果
     */
    @Override
    public int updateInvestigateDisposition(InvestigateDisposition investigateDisposition) {
        String url = investigateDisposition.getUrl();
        String path = url.replace("/profile", getProfile());
        // 删除原先的文件
        try {
            File file = new File(path);
            if (file.exists()){
                Runtime.getRuntime().exec("rm -f " + path);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        String fileName = getFileName(investigateDisposition);
        investigateDisposition.setUrl(fileName);
        InvestigateDisposition newParentInfo = investigateDispositionMapper.selectInvestigateDispositionById(investigateDisposition.getParentId());
        InvestigateDisposition oldInfo = investigateDispositionMapper.selectInvestigateDispositionById(investigateDisposition.getInvestigateDispositionId());
        if (StringUtils.isNotNull(newParentInfo) && StringUtils.isNotNull(oldInfo)) {
            String newAncestors = newParentInfo.getAncestors() + "," + newParentInfo.getInvestigateDispositionId();
            String oldAncestors = oldInfo.getAncestors();
            investigateDisposition.setAncestors(newAncestors);
            updateDeptChildren(investigateDisposition.getInvestigateDispositionId(), newAncestors, oldAncestors);
        }
        investigateDisposition.setUpdateTime(DateUtils.getNowDate());
        return investigateDispositionMapper.updateInvestigateDisposition(investigateDisposition);
    }

    @Override
    public int updateInvestigateDispositionStatus(InvestigateDisposition investigateDisposition) {
        investigateDisposition.setUpdateTime(DateUtils.getNowDate());
        return investigateDispositionMapper.updateInvestigateDisposition(investigateDisposition);
    }

    /**
     * 修改子元素关系
     *
     * @param investigateDispositionId 被修改的考察配置ID
     * @param newAncestors             新的父ID集合
     * @param oldAncestors             旧的父ID集合
     */
    public void updateDeptChildren(Long investigateDispositionId, String newAncestors, String oldAncestors) {
        List<InvestigateDisposition> children = investigateDispositionMapper.selectChildrenInvestigateDispositionById(investigateDispositionId);

        for (InvestigateDisposition child : children) {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (children.size() > 0) {
            investigateDispositionMapper.updateInvestigateDispositionChildren(children);
        }
    }

    /**
     * 批量删除考察配置
     *
     * @param investigateDispositionIds 需要删除的考察配置主键
     * @return 结果
     */
    @Override
    public int deleteInvestigateDispositionByInvestigateDispositionIds(Long[] investigateDispositionIds) {
        return investigateDispositionMapper.deleteInvestigateDispositionByInvestigateDispositionIds(investigateDispositionIds);
    }

    /**
     * 删除考察配置信息
     *
     * @param investigateDispositionId 考察配置主键
     * @return 结果
     */
    @Override
    public int deleteInvestigateDispositionByInvestigateDispositionId(Long investigateDispositionId) {
        return investigateDispositionMapper.deleteInvestigateDispositionByInvestigateDispositionId(investigateDispositionId);
    }


    /**
     * 查询部门树结构信息
     *
     * @param investigateDisposition 部门信息
     * @return 部门树信息集合
     */
    @Override
    public List<TreeSelect> selectInvestigateDispositionTreeList(InvestigateDisposition investigateDisposition) {
        List<InvestigateDisposition> investigateDispositions = selectInvestigateDispositionList(investigateDisposition);
        return buildInvestigateDispositionTreeSelect(investigateDispositions);
    }

    /**
     * 构建前端所需要树结构
     *
     * @param investigateDispositions 部门列表
     * @return 树结构列表
     */
    @Override
    public List<InvestigateDisposition> buildInvestigateDispositionTree(List<InvestigateDisposition> investigateDispositions) {
        List<InvestigateDisposition> returnList = new ArrayList<InvestigateDisposition>();
        List<Long> tempList = investigateDispositions.stream().map(InvestigateDisposition::getInvestigateDispositionId).collect(Collectors.toList());
        for (InvestigateDisposition investigateDisposition : investigateDispositions) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(investigateDisposition.getParentId())) {
                recursionFn(investigateDispositions, investigateDisposition);
                returnList.add(investigateDisposition);
            }
        }
        if (returnList.isEmpty()) {
            returnList = investigateDispositions;
        }
        return returnList;
    }

    /**
     * 构建前端所需要下拉树结构
     *
     * @param investigateDispositions 部门列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildInvestigateDispositionTreeSelect(List<InvestigateDisposition> investigateDispositions) {
        List<InvestigateDisposition> deptTrees = buildInvestigateDispositionTree(investigateDispositions);
        return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<InvestigateDisposition> list, InvestigateDisposition t) {
        // 得到子节点列表
        List<InvestigateDisposition> childList = getChildList(list, t);
        t.setChildren(childList);
        for (InvestigateDisposition tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<InvestigateDisposition> getChildList(List<InvestigateDisposition> list, InvestigateDisposition t) {
        List<InvestigateDisposition> tlist = new ArrayList<InvestigateDisposition>();
        Iterator<InvestigateDisposition> it = list.iterator();
        while (it.hasNext()) {
            InvestigateDisposition n = (InvestigateDisposition) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getInvestigateDispositionId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<InvestigateDisposition> list, InvestigateDisposition t) {
        return getChildList(list, t).size() > 0;
    }
}
