package com.ruoyi.gysl.service.impl;

import cn.hutool.core.io.resource.ClassPathResource;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.docking.entity.SmartDeclaration;
import com.ruoyi.docking.service.SmartDeclarationService;
import com.ruoyi.docking.service.UserService;
import com.ruoyi.gysl.entity.*;
import com.ruoyi.gysl.entity.request.AuditRequest;
import com.ruoyi.gysl.entity.request.BasicInformationPageReq;
import com.ruoyi.gysl.entity.request.RemarkPageReq;
import com.ruoyi.gysl.entity.request.ZwIdPageReq;
import com.ruoyi.gysl.entity.response.BasicInformationResponse;
import com.ruoyi.gysl.entity.response.ProjectExcelInfo;
import com.ruoyi.gysl.mapper.BasicInformationMapper;
import com.ruoyi.gysl.service.*;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 基本信息(BasicInformation)表服务实现类
 *
 * @author makejava
 * @since 2025-02-24 09:25:55
 */
@Service("basicInformationService")
public class BasicInformationServiceImpl extends ServiceImpl<BasicInformationMapper, BasicInformation> implements BasicInformationService {


    /**
     * 项目规划信息
     */
    @Resource
    private PlanInformationService planInformationService;


    /**
     * 建筑信息
     */
    @Resource
    private BuildingInformationService buildingInformationService;

    /**
     * 五要素模型信息
     */
    @Resource
    private WysmxInformationService wysmxInformationService;

    /**
     * 企业入驻信息
     */
    @Resource
    private QyrzInformationService qyrzInformationService;

    /**
     * 项目图例信息
     */
    @Resource
    private ProjectLegendService projectLegendService;

    /**
     * 项目备忘录
     */
    @Resource
    private ProjectRemarkService projectRemarkService;

    /**
     * 月度进展信息
     */
//    @Resource
//    private ProjectMonthInfoService projectMonthInfoService;

    @Resource
    private SmartDeclarationService smartDeclarationService;

    @Resource
    private UserService userService;

    /**
     * 项目巡礼
     */
    @Resource
    private XmxlService xmxlService;

    /**
     * 项目备忘录
     */
    @Resource
    private ProjectOtherInfoService otherInfoService;

    /**
     * 入驻的企业
     */
    @Resource
    private EnterpriseService enterpriseService;

    @Resource
    private GyslBqglService gyslBqglService;

    /**
     * 分页查询所有数据
     *
     * @param page 分页对象
     * @param req  查询实体
     * @return 所有数据
     */
    @Override
    public Page<BasicInformation> page(Page<BasicInformation> page, BasicInformationPageReq req) {
        return baseMapper.page(page, req);
    }


    /**
     * 导出项目数据
     */
    @Override
    public List<ProjectExcelInfo> selectList() {
        return baseMapper.selectProjectList();
    }


    /**
     * 有经纬度的项目列表
     */
    @Override
    public Page<BasicInformation> projectList(Page<BasicInformation> page) {
        return baseMapper.projectList(page);
    }

    /**
     * 查看当前用户是否有权限查看或者修改新增
     */
    @Override
    public BasicInformation testXmId(Serializable xmId) {
        BasicInformation byId = getById(xmId);
        // 获取当前登录用户是否是企业端
        try {
            if (SecurityUtils.hasRole("company") && byId != null) {
                if (!Objects.equals(byId.getTyshxydm(), SecurityUtils.getUsername())) {
                    throw new ServiceException("禁止修改!");
                }
            }
        } catch (Exception ignored) {
        }
        return byId;
    }

    /**
     * 企业端和政务端信息修改
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long audit(AuditRequest req, int status, int oldStatus) {
        //企业端提交审核直接修改，不需要挂起等待审批
        //修改项目基本信息，和是否是负面清单
        List<WysmxInformation> collect1 = req.getWysmxInformations().stream().filter(x -> "危化品等级".equals(x.getZdname())).collect(Collectors.toList());
        List<WysmxInformation> collect2 = req.getWysmxInformations().stream().filter(x -> "生产火灾危险等级".equals(x.getZdname())).collect(Collectors.toList());
        List<WysmxInformation> collect3 = req.getWysmxInformations().stream().filter(x -> "环境保护".equals(x.getZdname())).collect(Collectors.toList());
        if (!collect1.isEmpty() && !collect2.isEmpty() && !collect3.isEmpty()) {
            req.getBasicInformation().setIsFmqd(wysmxInformationService.canGoUpstairs(collect1.get(0).getZdinfor(), collect2.get(0).getZdinfor(), collect3.get(0).getZdinfor()) ? 1 : 0);
        }

        //修改项目规划信息
        planInformationService.updateById(req.getPlanInformation());
        //修改企业入驻信息
        qyrzInformationService.updateById(req.getQyrzInformation());
        //修改五要素模型信息
        wysmxInformationService.lambdaUpdate().eq(WysmxInformation::getXmId, req.getBasicInformation().getId()).remove();
        wysmxInformationService.saveBatch(req.getWysmxInformations());
        //修改其他信息
        otherInfoService.lambdaUpdate().eq(ProjectOtherInfo::getXmId, req.getBasicInformation().getId()).remove();
        otherInfoService.saveBatch(req.getProjectOtherInfos());

        if (status == 2) {
            if (oldStatus == 1) {
                userService.getAllZwUser("关于" + req.getBasicInformation().getName() + "项目,待审核的通知", req.getBasicInformation().getId(), null, String.valueOf(LocalDateTime.now()));
            }
        }
        if (status == 3) {
            if (oldStatus == 2) {
                SmartDeclaration sd = new SmartDeclaration();
                sd.setAlertTime(LocalDateTime.now());
                sd.setTyshxydm((req.getBasicInformation().getTyshxydm()));
                sd.setProjectId(req.getBasicInformation().getId());
                sd.setContent("关于" + req.getBasicInformation().getName() + "项目,审核通过的通知");
                smartDeclarationService.save(sd);
            }
        }
        req.getBasicInformation().setStatus(status);
        updateById(req.getBasicInformation());
        return req.getBasicInformation().getId();
    }

    /**
     * 通过主键查询单条项目所有数据(政务端)
     *
     * @param id 主键
     * @return 单条数据
     */
    @Override
    public BasicInformationResponse selectOne(Long id) {

        BasicInformationResponse basicInformationResponse = new BasicInformationResponse();
        //项目基本信息
        BasicInformation byId = getById(id);
        basicInformationResponse.setBasicInformation(byId == null ? new BasicInformation() : byId);
        //项目规划信息
        PlanInformation one = planInformationService.lambdaQuery().eq(PlanInformation::getXmId, id).one();
        basicInformationResponse.setPlanInformation(one == null ? new PlanInformation() : one);
        //项目建筑信息
        basicInformationResponse.setBuildingInformation(buildingInformationService.lambdaQuery().eq(BuildingInformation::getXmId, id).list());
        //五要素模型信息
        ZwIdPageReq zwIdPageReq = new ZwIdPageReq();
        zwIdPageReq.setXmId(id);
        basicInformationResponse.setWysmxResponses(wysmxInformationService.list(zwIdPageReq));
        //企业入驻信息
        QyrzInformation qyrzInformation = qyrzInformationService.selectAll(zwIdPageReq);
        basicInformationResponse.setQyrzInformation(qyrzInformation == null ? new QyrzInformation() : qyrzInformation);
        //项目图例
        basicInformationResponse.setProjectLegendResponses(projectLegendService.page(zwIdPageReq));
        //项目巡礼
        basicInformationResponse.setXmxl(xmxlService.list(zwIdPageReq));
        RemarkPageReq remarkPageReq = new RemarkPageReq();
        remarkPageReq.setXmId(id);
        //项目备忘录
        basicInformationResponse.setProjectRemarks(projectRemarkService.list(remarkPageReq));
        //其他信息
        basicInformationResponse.setProjectOtherInfos(otherInfoService.searchId(zwIdPageReq));
        //标签管理
        basicInformationResponse.setBqglResponses(gyslBqglService.searchId(zwIdPageReq));
        return basicInformationResponse;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeByXmIds(List<Long> idList) {
        idList.forEach(x -> {
            //删除项目基本信息
            lambdaUpdate().eq(BasicInformation::getId, x).remove();
            //删除项目规划信息
            planInformationService.lambdaUpdate().eq(PlanInformation::getXmId, x).remove();
            //删除项目建筑信息
            buildingInformationService.lambdaUpdate().eq(BuildingInformation::getXmId, x).remove();
            //删除五要素模型信息
            wysmxInformationService.lambdaUpdate().eq(WysmxInformation::getXmId, x).remove();
            //删除月度进展信息
//            projectMonthInfoService.lambdaUpdate()
//                    .eq(ProjectMonthInfo::getXmId,x)
//                    .remove();
            //删除企业入驻信息
            qyrzInformationService.lambdaUpdate().eq(QyrzInformation::getXmId, x).remove();
            //删除项目图例
            projectLegendService.lambdaUpdate().eq(ProjectLegend::getXmId, x).remove();
            //删除项目巡礼
            xmxlService.lambdaUpdate().eq(Xmxl::getXmId, x).remove();
            //删除项目备忘录
            projectRemarkService.lambdaUpdate().eq(ProjectRemark::getXmId, x).remove();
            //删除其他信息
            otherInfoService.lambdaUpdate().eq(ProjectOtherInfo::getXmId, x).remove();
            //删除标签管理
            gyslBqglService.lambdaUpdate().eq(GyslBqgl::getXmId, x).remove();
        });
    }

    /**
     * 企业端暂存
     */
    @Override
    public Long staging(AuditRequest req) {
        //先删再暂存，因为可能会多次暂存
        baseMapper.delete1(req.getBasicInformation().getId());
        baseMapper.delete2(req.getBasicInformation().getId());
        baseMapper.delete3(req.getBasicInformation().getId());
        baseMapper.delete4(req.getBasicInformation().getId());
        baseMapper.delete5(req.getBasicInformation().getId());

        baseMapper.insert1(req.getBasicInformation());
        baseMapper.insert2(req.getPlanInformation());

        req.getWysmxInformations().forEach(x -> baseMapper.insert3(x));

        baseMapper.insert4(req.getQyrzInformation());
        req.getProjectOtherInfos().forEach(x -> baseMapper.insert5(x));
        return req.getBasicInformation().getId();
    }

    /**
     * 通过主键查询单条项目所有数据(企业端)
     *
     * @param id 主键
     * @return 单条数据
     */
    @Override
    public BasicInformationResponse stagingInfo(Long id) {
        BasicInformationResponse basicInformationResponse = new BasicInformationResponse();
        //项目基本信息
        BasicInformation bs = baseMapper.select1(id);
        if (bs != null) {
            basicInformationResponse.setBasicInformation(bs);
        } else {
            BasicInformation byId = getById(id);
            basicInformationResponse.setBasicInformation(byId == null ? new BasicInformation() : byId);
        }
        //项目规划信息
        PlanInformation pl = baseMapper.select2(id);
        if (pl != null) {
            basicInformationResponse.setPlanInformation(pl);
        } else {
            PlanInformation one = planInformationService.lambdaQuery().eq(PlanInformation::getXmId, id).one();
            basicInformationResponse.setPlanInformation(one == null ? new PlanInformation() : one);
        }
        //项目建筑信息
        basicInformationResponse.setBuildingInformation(buildingInformationService.lambdaQuery().eq(BuildingInformation::getXmId, id).list());
        //五要素模型信息
        ZwIdPageReq zwIdPageReq = new ZwIdPageReq();
        zwIdPageReq.setXmId(id);
        List<WysmxInformation> wm = baseMapper.select3(id);
        if (!wm.isEmpty()) {
            basicInformationResponse.setWysmxResponses(wysmxInformationService.getWysFinal(wm));
        } else {
            basicInformationResponse.setWysmxResponses(wysmxInformationService.list(zwIdPageReq));
        }
        //企业入驻信息
        QyrzInformation qi = baseMapper.select4(id);
        if (qi != null) {
            basicInformationResponse.setQyrzInformation(qi);
        } else {
            QyrzInformation qyrzInformation = qyrzInformationService.selectAll(zwIdPageReq);
            basicInformationResponse.setQyrzInformation(qyrzInformation == null ? new QyrzInformation() : qyrzInformation);
        }
        //项目图例
        basicInformationResponse.setProjectLegendResponses(projectLegendService.page(zwIdPageReq));
        //项目巡礼
        basicInformationResponse.setXmxl(xmxlService.list(zwIdPageReq));
        RemarkPageReq remarkPageReq = new RemarkPageReq();
        remarkPageReq.setXmId(id);
        //项目备忘录
        basicInformationResponse.setProjectRemarks(projectRemarkService.list(remarkPageReq));
        //其他信息
        List<ProjectOtherInfo> po = baseMapper.select5(id);
        if (!po.isEmpty()) {
            basicInformationResponse.setProjectOtherInfos(po);
        } else {
            basicInformationResponse.setProjectOtherInfos(otherInfoService.searchId(zwIdPageReq));
        }
        //标签管理
        basicInformationResponse.setBqglResponses(gyslBqglService.searchId(zwIdPageReq));
        return basicInformationResponse;
    }

    /**
     * 根据材料返回输chu流
     */
    @Override
    public void generateDocument(Map<String, Object> map, String docx, OutputStream sr) throws IOException {
        ClassPathResource resource = new ClassPathResource(docx);
        try (InputStream is = resource.getStream();
             XWPFDocument doc = new XWPFDocument(is);
        ) {
            // 处理段落
            for (XWPFParagraph paragraph : doc.getParagraphs()) {
                List<XWPFRun> runs = paragraph.getRuns();
                if (runs == null) continue;
                for (XWPFRun run : runs) {
                    String text = run.getText(0);
                    if (text == null) continue;
                    // 动态替换所有模板变量
                    for (Map.Entry<String, Object> entry : map.entrySet()) {
                        if (text.contains(entry.getKey())) {
                            text = text.replace(entry.getKey(), entry.getValue() != null ? entry.getValue().toString() : "");
                            run.setText(text, 0);
                        }
                    }
                }
            }
            doc.write(sr);
        } catch (Exception e) {
            throw new IOException("文档生成失败", e);
        }
    }


    /**
     * 根据dict_type和dict_value返回
     */
    @Override
    public String getDictLabel(String dictType, String dictValue, List<SysDictData> sysDictData) {
        List<SysDictData> collect = sysDictData.stream().filter(x ->
                        x.getDictType().equals(dictType) && x.getDictValue().equals(dictValue))
                .collect(Collectors.toList());
        if (collect.isEmpty()) {
            return "/";
        } else {
            return collect.get(0).getDictLabel();
        }
    }
}
