package com.yeejoin.amos.boot.module.ugp.biz.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.biz.common.utils.QRCodeUtil;
import com.yeejoin.amos.boot.module.ugp.api.Enum.NoticeStatusEnum;
import com.yeejoin.amos.boot.module.ugp.api.Enum.ProcessTypeEnum;
import com.yeejoin.amos.boot.module.ugp.api.Enum.ProjectInitiationEnum;
import com.yeejoin.amos.boot.module.ugp.api.Enum.ProjectResourceEnum;
import com.yeejoin.amos.boot.module.ugp.api.dto.InstallNoticePageDto;
import com.yeejoin.amos.boot.module.ugp.api.dto.ProjectDto;
import com.yeejoin.amos.boot.module.ugp.api.entity.*;
import com.yeejoin.amos.boot.module.ugp.api.mapper.InstallNoticeMapper;
import com.yeejoin.amos.boot.module.ugp.api.service.IInstallNoticeService;
import com.yeejoin.amos.boot.module.ugp.api.dto.InstallNoticeDto;
import com.yeejoin.amos.boot.module.ugp.biz.fegin.TzsServiceFeignClient;
import com.yeejoin.amos.boot.module.ugp.biz.framework.BusinessIdentify;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import org.apache.http.entity.ContentType;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseHelper;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Wrapper;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 安装告知表服务实现类
 *
 * @author system_generator
 * @date 2022-09-22
 */
@Service
public class InstallNoticeServiceImpl extends BaseService<InstallNoticeDto,InstallNotice,InstallNoticeMapper> implements IInstallNoticeService{

    @Autowired
    InstallNoticeMapper installNoticeMapper;
    @Autowired
    ProjectServiceImpl projectServiceImpl;
    @Autowired
    ProjectInitiationServiceImpl projectInitiationServiceImpl;
    @Autowired
    OrgServiceImpl orgServiceImpl;
    @Autowired
    ProjectResourceServiceImpl projectResourceServiceImpl;
    @Autowired
    SuperviseRuleServiceImpl superviseRuleServiceImpl;
    @Autowired
    UnitLicenceServiceImpl unitLicenceService;

    @Autowired
    IPipeServiceImpl pipeService;

    @Autowired
    ProjectResourceServiceImpl projectResourceService;

    @Autowired
    MaterialServiceImpl materialService;

    @Autowired
    TzsServiceFeignClient tzsServiceFeignClient;
    @Autowired
    ProcessRelationServiceImpl processRelationService;
    /**
     * 分页查询
     */
    public Page<InstallNoticeDto> queryForInstallNoticePage(Page<InstallNoticeDto> page)   {
        return this.queryForPage(page, null, false);
    }

    /**
     * 列表查询 示例
     */
    public List<InstallNoticeDto> queryForInstallNoticeList()   {
        return this.queryForList("" , false);
    }

    /**
     * 安装告知申请分页查询
     */
    public Page<InstallNoticePageDto> installNoticePage(Page<InstallNoticePageDto> page,String name,String constructionUnit)   {
        List<Project> projectList = projectResourceServiceImpl.getProjectList();
        Set<String> ids = new HashSet<>();
        for(Project project : projectList){
            String id = String.valueOf(project.getSequenceNbr());
            ids.add(id);
        }

        if(ValidationUtil.isEmpty(ids)){
            return page;
        }

        Page<InstallNoticePageDto> installNoticePage = installNoticeMapper.installNoticePage(page,name,constructionUnit,ids);
        List<InstallNoticePageDto> installNoticePageDtos = installNoticePage.getRecords();
        for(InstallNoticePageDto installNoticePageDto:installNoticePageDtos){
            if(!ValidationUtil.isEmpty(installNoticePageDto.getApproved())){
                if(installNoticePageDto.getApproved()){
                    installNoticePageDto.setApprovedName("通过");
                }else{
                    installNoticePageDto.setApprovedName("不通过");
                }
            }
        }
        return installNoticePage;
    }

    /**
     * 根据sequenceNbr查询告知申请详情
     * @param sequenceNbr
     * @return
     */
    public InstallNoticeDto selectOneById(Long sequenceNbr){
        return installNoticeMapper.selectoneById(sequenceNbr);
    }

    /**
     * 新增安装告知申请,保存/提交
     *
     * @return
     */
     public InstallNoticeDto saveInstallNotice(JSONObject object, String noticeStatus,String installId ) {
         Long projectId = object.getLong("projectId");
         if(!ValidationUtil.isEmpty(installId)){
             projectId = this.getById(installId).getProjectId();
         }

        InstallNoticeDto installNoticeDto = new InstallNoticeDto();
		final ProjectDto projectDto = projectServiceImpl.queryBySeq(projectId);
        installNoticeDto.setProjectId(projectId);
        installNoticeDto.setProjectName(projectDto.getName());
        installNoticeDto.setCompanyName(projectDto.getInstallationUnit());
        installNoticeDto.setNoticeStatus(noticeStatus);
        installNoticeDto.setNoticeDate(new Date());
        installNoticeDto.setApproved(false);
        installNoticeDto.setInstallPri(object.getString("installPri"));
		installNoticeDto.setOrganizationCode(orgServiceImpl.getOrgUsr().getBizOrgCode());
        installNoticeDto.setLicenseNum(object.getString("licenseNum"));
        installNoticeDto.setLicenseCompany(object.getString("licenseCompany"));
//        final JSONArray licenseAttch = object.getJSONArray("licenseAttch");
        final JSONArray contractAttch = object.getJSONArray("contractAttch");
//        installNoticeDto.setLicenseAttch(JSON.toJSONString(licenseAttch));
        installNoticeDto.setContractAttch(JSON.toJSONString(contractAttch));
        installNoticeDto.setOrganizationCode(orgServiceImpl.getOrgUsr().getBizOrgCode());

        InstallNotice installNotice = new InstallNotice();
        LambdaQueryWrapper<InstallNotice> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InstallNotice :: getProjectId,projectId);
        List<InstallNotice> installNoticeList = this.list(wrapper);
        if(!ValidationUtil.isEmpty(installNoticeList)){
            installNotice = installNoticeList.iterator().next();
            installNoticeDto.setSequenceNbr(installNotice.getSequenceNbr());
        }

        BeanUtils.copyProperties(installNoticeDto,installNotice);
        this.saveOrUpdate(installNotice);

        if(NoticeStatusEnum.已提交.getName().equals(noticeStatus)){
            projectInitiationServiceImpl.execute(projectDto.getInstanceId(),installNoticeDto,"1",null);
        }
        return  installNoticeDto;
    }

    /**
     * 根据sequenceNbr查询安装告知信息及附件
     *
     * @param sequenceNbr  主键
     * @return
     */
    public JSONObject selectOneBySeq(Long sequenceNbr) {
        JSONObject jsonObject = new JSONObject();
        final InstallNoticeDto installNoticeDto = selectOneById(sequenceNbr);
        //项目信息
        final ProjectDto projectDto = projectServiceImpl.queryBySeq(installNoticeDto.getProjectId());
        SuperviseRule superviseRule = superviseRuleServiceImpl.getOne(new LambdaQueryWrapper<SuperviseRule>().eq(SuperviseRule::getAdminRegionCode,projectDto.getInstallRegionCode()));
        Map map = new org.apache.commons.beanutils.BeanMap(projectDto);
        jsonObject.putAll(map);
        //项目指定的安装单位的许可信息
        Long companyId = projectDto.getInstallationUnitId();
        jsonObject = unitLicenceService.getLicenceByCompanyId(jsonObject,companyId);

        if(!ValidationUtil.isEmpty(superviseRule)){
            jsonObject.put("inspectionUnit",orgServiceImpl.getdetialInfo(String.valueOf(superviseRule.getInspectionUnitId())).get("name"));
            jsonObject.put("superviseDept",orgServiceImpl.getdetialInfo(String.valueOf(superviseRule.getSuperviseDeptId())).get("name"));
        }
//        jsonObject.put("name",projectDto.getName());
//        jsonObject.put("installRegion",projectDto.getInstallRegion());
        jsonObject.put("licenseNum",installNoticeDto.getLicenseNum());
        jsonObject.put("licenseCompany",installNoticeDto.getLicenseCompany());
//        jsonObject.put("licenseAttch",JSON.parseArray(installNoticeDto.getLicenseAttch()));
        jsonObject.put("contractAttch",JSON.parseArray(installNoticeDto.getContractAttch()));
        jsonObject.put("installPri",installNoticeDto.getInstallPri());
        jsonObject.put("projectId",map.get("sequenceNbr"));
        return jsonObject;
    }

    public InstallNoticeDto getInfoByProjectId(Long projectId){
        LambdaQueryWrapper<InstallNotice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(InstallNotice::getProjectId, projectId);
        lambdaQueryWrapper.eq(InstallNotice::getIsDelete, Boolean.FALSE);
        InstallNotice one = this.getOne(lambdaQueryWrapper);
        ProjectDto projectDto = projectServiceImpl.getDetail(projectId);
        InstallNoticeDto installNoticeDto = new InstallNoticeDto();
        if (ObjectUtils.isNotEmpty(one)) {
            BeanUtils.copyProperties(one, installNoticeDto);
        }
        installNoticeDto.setProjectCode(projectDto.getCode());
        installNoticeDto.setDesign(projectDto.getDesignUnit());
        installNoticeDto.setInstall(projectDto.getInstallationUnit());
        installNoticeDto.setImplementDate(projectDto.getStartDate());
        installNoticeDto.setConstructionUnit(projectDto.getInstallationUnit());
        installNoticeDto.setUseUnitName(orgServiceImpl.getOrgUsr().getBizOrgName());
        //查询设备型号(参数)
        LambdaQueryWrapper<Pipe> lambda = new LambdaQueryWrapper<>();
        lambda.eq(Pipe::getProjectId, projectId);
        lambda.eq(Pipe::getIsDelete, Boolean.FALSE);
        List<Pipe> list = pipeService.list(lambda);
        String specifications = list.stream().map(Pipe::getSpecification).distinct().collect(Collectors.joining(","));
        installNoticeDto.setEquipType(specifications);
        //查询制造单位信息
        LambdaQueryWrapper<ProjectResource> lambdaProjectResource = new LambdaQueryWrapper<>();
        lambdaProjectResource.eq(ProjectResource::getProjectId, projectId);
        lambdaProjectResource.eq(ProjectResource::getType, ProjectResourceEnum.管材资源.getCode());
        lambdaProjectResource.eq(ProjectResource::getIsDelete, 0);
        List<Long> collect1 = projectResourceService.list(lambdaProjectResource).stream().map(ProjectResource::getResourceId).distinct().collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(collect1)) {
            LambdaQueryWrapper<Material> materialLambdaQueryWrapper = new LambdaQueryWrapper<>();
            materialLambdaQueryWrapper.in(Material::getSequenceNbr, collect1);
            materialLambdaQueryWrapper.eq(Material::getIsDelete, Boolean.FALSE);
            List<String> collect = materialService.list(materialLambdaQueryWrapper).stream().map(Material::getManufacturer).distinct().collect(Collectors.toList());
            ResponseModel<List<UnitLicence>> licenceByCompanyName = tzsServiceFeignClient.getLicenceByCompanyName(collect);
            String manufacturers = String.join(",", collect);
            String cerNos = licenceByCompanyName.getResult().stream().map(UnitLicence::getCertNo).collect(Collectors.joining(","));
            installNoticeDto.setMadeUnit(manufacturers);
            installNoticeDto.setMadeLicenceCode(cerNos);
        }
        List<String> list1 = Collections.singletonList(projectDto.getInstallationUnit());
        ResponseModel<List<UnitLicence>> buildLicenceInfo = tzsServiceFeignClient.getLicenceByCompanyName(list1);
        String buildLicenceCode = buildLicenceInfo.getResult().stream().map(UnitLicence::getCertNo).collect(Collectors.joining(","));
        SimpleDateFormat sdf = new SimpleDateFormat(DateUtils.DATE_PATTERN);
        String collect = buildLicenceInfo.getResult().stream().map(t -> sdf.format(t.getExpiryDate())).collect(Collectors.joining(","));
        installNoticeDto.setBuildLicenceCode(buildLicenceCode);
        installNoticeDto.setBuildLicenceDateLine(collect);
        installNoticeDto.setProjectId(projectId);
        LambdaQueryWrapper<ProcessRelation> relationsWrapper = new LambdaQueryWrapper<>();
        relationsWrapper.eq(ProcessRelation::getSourceId,projectDto.getSequenceNbr())
                .eq(ProcessRelation::getDefCode, ProcessTypeEnum.项目立项.getType());
        ProcessRelation processRelation = processRelationService.getOne(relationsWrapper);
        installNoticeDto.setInstanceId(org.springframework.util.ObjectUtils.isEmpty(processRelation) ? null : processRelation.getInstanceId());
        if (ObjectUtils.isNotEmpty(processRelation)) {
            LambdaQueryWrapper<ProjectInitiation> logLambda = new LambdaQueryWrapper<>();
            logLambda.eq(ProjectInitiation::getTaskName, ProjectInitiationEnum.接受告知.getName());
            logLambda.eq(ProjectInitiation::getInstanceId, org.springframework.util.ObjectUtils.isEmpty(processRelation) ? null : processRelation.getInstanceId());
            logLambda.orderByDesc(ProjectInitiation::getRecDate);
            logLambda.last("limit 1");
            ProjectInitiation logObject = projectInitiationServiceImpl.getOne(logLambda);
            if (ObjectUtils.isNotEmpty(logObject)) {
                String context = logObject.getContext();
                JSONObject jsonObject = JSONObject.parseObject(context);
                installNoticeDto.setAuditOpinion(jsonObject.getString("auditOpinion"));
            }
        }
        return installNoticeDto;
    }
}