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.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.yeejoin.amos.boot.module.ugp.api.Enum.OrgEnum;
import com.yeejoin.amos.boot.module.ugp.api.Enum.ProjectResourceEnum;
import com.yeejoin.amos.boot.module.ugp.api.dto.AttachmentDto;
import com.yeejoin.amos.boot.module.ugp.api.dto.MaterialCount;
import com.yeejoin.amos.boot.module.ugp.api.dto.MaterialDto;
import com.yeejoin.amos.boot.module.ugp.api.entity.*;
import com.yeejoin.amos.boot.module.ugp.api.mapper.AttachmentMapper;
import com.yeejoin.amos.boot.module.ugp.api.mapper.CompanyMapper;
import com.yeejoin.amos.boot.module.ugp.api.mapper.MaterialMapper;
import com.yeejoin.amos.boot.module.ugp.api.mapper.SuperviseRuleMapper;
import com.yeejoin.amos.boot.module.ugp.api.service.IMaterialService;
import com.yeejoin.amos.boot.module.ugp.biz.framework.BusinessIdentify;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import java.util.*;

/**
 * 材料信息表服务实现类
 *
 * @author system_generator
 * @date 2022-09-22
 */
@Service
public class MaterialServiceImpl extends BaseService<MaterialDto, Material, MaterialMapper> implements IMaterialService {

    @Autowired
    AttachmentServiceImpl attachmentServiceImpl;
    @Autowired
    AttachmentMapper attachmentMapper;
    @Autowired
    OrgServiceImpl orgService;
    @Autowired
    MaterialMapper materialMapper;
    @Autowired
    CompanyMapper companyMapper;
    @Autowired
    SuperviseRuleMapper superviseRuleMapper;

    @Autowired
    SuperviseRuleServiceImpl superviseRuleService;
    @Autowired
    CompanyServiceImpl companyService;

    @Autowired
    ProjectServiceImpl projectService;

    @Autowired
    ProjectResourceServiceImpl projectResourceServiceImpl;

    @Autowired
    AttachmentServiceImpl attachmentService;

    /**
     * 分页查询
     */
    @BusinessIdentify
    public IPage<Material> queryForMaterialPage(IPage<Material> page, String name , String code) {

        LambdaQueryWrapper<Material> wrapper = new LambdaQueryWrapper<>();
        if(!ValidationUtil.isEmpty(name)){
            wrapper.like(Material::getName,name);
        }
        if(!ValidationUtil.isEmpty(code)){
            wrapper.like(Material::getCode,code);
        }
        wrapper.in(Material::getCompanyId,getCompanyIds());
        return this.page(page,wrapper);
    }

    /**
     * 提交资料 获取管材列表 分页查询 projectId关联的资源
     */
    public IPage<MaterialDto> queryOutPage(IPage<Material> page, MaterialDto material) {
        LambdaQueryWrapper<Material> wrapper = new LambdaQueryWrapper<>();
        List materialIds = new ArrayList<>();
        LambdaQueryWrapper<ProjectResource> resourceWrapper = new LambdaQueryWrapper<>();
        if(!ValidationUtil.isEmpty(material.getProjectId())){
            resourceWrapper.eq(ProjectResource::getProjectId,material.getProjectId())
                    .eq(ProjectResource::getType, ProjectResourceEnum.管材资源.getCode());
            List<ProjectResource> list = projectResourceServiceImpl.list(resourceWrapper);
            for (ProjectResource projectResource: list) {
                materialIds.add(projectResource.getResourceId());
            }
            if (ObjectUtils.isEmpty(list)){
                return new Page<>();
            }
            wrapper.in(Material::getSequenceNbr,materialIds);
        }

        getWrapper(wrapper,material);
        page = this.page(page,wrapper);
        IPage<MaterialDto> dtoPage = new Page<>();
        BeanUtils.copyProperties(page,dtoPage);
        List<Material> materialList = page.getRecords();
        List<MaterialDto> materialDtoList = new ArrayList<>();
        if(!ValidationUtil.isEmpty(materialList)) {
            for(Material mt : materialList) {
                MaterialDto materialDto = new MaterialDto();
                BeanUtils.copyProperties(mt,materialDto);
                materialDto.setFiles(attachmentService.getFilesBySourceId(mt.getSequenceNbr()));
                materialDtoList.add(materialDto);
            }
        }
        dtoPage.setRecords(materialDtoList);
        return dtoPage;
    }

    /**
     * 提交资料 获取管材列表 分页查询 projectId关联的资源和空闲的资源
     */
    public IPage<MaterialDto> queryInPage(IPage<Material> page, MaterialDto material) {
        LambdaQueryWrapper<Material> wrapper = new LambdaQueryWrapper<>();
        List materialIds = new ArrayList<>();
        LambdaQueryWrapper<ProjectResource> resourceWrapper = new LambdaQueryWrapper<>();
        if(!ValidationUtil.isEmpty(material.getProjectId())){
            resourceWrapper.ne(ProjectResource::getProjectId,material.getProjectId())
                    .eq(ProjectResource::getType, ProjectResourceEnum.管材资源.getCode());
            List<ProjectResource> list = projectResourceServiceImpl.list(resourceWrapper);
            for (ProjectResource projectResource: list) {
                materialIds.add(projectResource.getResourceId());
            }
            wrapper.notIn(Material::getSequenceNbr,materialIds);
        }

        getWrapper(wrapper,material);
        wrapper.in(Material::getCompanyId,getCompanyIds());

        page = this.page(page,wrapper);
        IPage<MaterialDto> dtoPage = new Page<>();
        BeanUtils.copyProperties(page,dtoPage);
        List<Material> materialList = page.getRecords();
        List<MaterialDto> materialDtoList = new ArrayList<>();
        if(!ValidationUtil.isEmpty(materialList)) {
            for(Material mt : materialList) {
                MaterialDto materialDto = new MaterialDto();
                BeanUtils.copyProperties(mt,materialDto);
                materialDto.setFiles(attachmentService.getFilesBySourceId(mt.getSequenceNbr()));
                materialDtoList.add(materialDto);
            }
        }
        dtoPage.setRecords(materialDtoList);

        return dtoPage;
    }

    public void getWrapper(LambdaQueryWrapper<Material> wrapper,MaterialDto material){
        if(!ValidationUtil.isEmpty(material.getName())){
            wrapper.like(Material::getName,material.getName());
        }
        if(!ValidationUtil.isEmpty(material.getCode())){
            wrapper.like(Material::getCode,material.getCode());
        }
        if(!ValidationUtil.isEmpty(material.getType())){
            wrapper.like(Material::getType,material.getType());
        }
        if(!ValidationUtil.isEmpty(material.getMaterial())){
            wrapper.like(Material::getMaterial,material.getMaterial());
        }
        if(!ValidationUtil.isEmpty(material.getManufactureDate())){
            wrapper.like(Material::getManufactureDate,material.getManufactureDate());
        }
        if(!ValidationUtil.isEmpty(material.getSpec())){
            wrapper.like(Material::getSpec,material.getSpec());
        }
        if(!ValidationUtil.isEmpty(material.getBatchNum())){
            wrapper.like(Material::getBatchNum,material.getBatchNum());
        }
        if(!ValidationUtil.isEmpty(material.getApproved())){
            wrapper.like(Material::getApproved,material.getApproved());
        }
        if(!ValidationUtil.isEmpty(material.getCompanyId())){
            wrapper.like(Material::getCompanyId,material.getCompanyId());
        }
        if(!ValidationUtil.isEmpty(material.getDiameter())){
            wrapper.like(Material::getDiameter,material.getDiameter());
        }
        if(!ValidationUtil.isEmpty(material.getLength())){
            wrapper.like(Material::getLength,material.getLength());
        }
        if(!ValidationUtil.isEmpty(material.getManufactureAddr())){
            wrapper.like(Material::getManufactureAddr,material.getManufactureAddr());
        }
        if(!ValidationUtil.isEmpty(material.getOrgCode())){
            wrapper.like(Material::getOrgCode,material.getOrgCode());
        }
        if(!ValidationUtil.isEmpty(material.getWallThickness())){
            wrapper.like(Material::getWallThickness,material.getWallThickness());
        }
    }

    @BusinessIdentify
    public Set<Long> getCompanyIds(){
        List<String> regionCodeList = new ArrayList<>();
        Set<Long> companyIds = new HashSet<>();
        Long companyId = orgService.getReginParams().getBusinessInfo().getCompanySequenceNbr();
        companyIds.add(companyId);
        String companyType = orgService.getReginParams().getBusinessInfo().getCompanyType();
        if(OrgEnum.监察部门.getKey().equals(companyType) || OrgEnum.监检机构.getKey().equals(companyType)) {
            LambdaQueryWrapper<SuperviseRule> wrapper = new LambdaQueryWrapper<>();
            if (OrgEnum.监察部门.getKey().equals(companyType)) {
                wrapper.eq(SuperviseRule::getSuperviseDeptId, companyId);
            } else if (OrgEnum.监检机构.getKey().equals(companyType)) {
                wrapper.eq(SuperviseRule::getInspectionUnitId, companyId);
            }
            List<SuperviseRule> superviseRuleList = superviseRuleService.list(wrapper);
            for (SuperviseRule superviseRule : superviseRuleList) {
                regionCodeList.add(String.valueOf(superviseRule.getAdminRegionCode()));
            }

            LambdaQueryWrapper<Company> companyWrapper = new LambdaQueryWrapper<>();
            companyWrapper.in(Company::getRegionCode, regionCodeList);

            List<Company> companyList = companyService.list(companyWrapper);
            for (Company company : companyList) {
                companyIds.add(company.getSequenceNbr());
            }
        }

        return companyIds;

    }

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


    /**
     * 获取材料名称跟企业id
     */
    @BusinessIdentify
    public List<JSONObject> selectName() {
        List<JSONObject> names = new ArrayList<>();
        //添加查询条件
        Long companySequenceNbr = orgService.getReginParams().getBusinessInfo().getCompanySequenceNbr();
        LambdaQueryWrapper<Material> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Material::getCompanyId,companySequenceNbr);
//        List<Equipment> equipment = equipmentMapper.selectList(wrapper);
//        QueryWrapper<Material> wrapper = new QueryWrapper<>();
//        wrapper.eq("company_id", installationUnitId);

        List<Material> materials = baseMapper.selectList(wrapper);

        for (Material i : materials) {
            JSONObject name = new JSONObject();
            name.put("name", i.getName());
            name.put("SequenceNbr", i.getSequenceNbr());
            names.add(name);
        }

        return names;
    }
    /**
     * 新增材料
     */
    @Override
    @BusinessIdentify
    public MaterialDto saveMaterial(JSONObject jsonObject){
        MaterialDto materialDto = new MaterialDto();
        materialDto.setRecDate(new Date());
        materialDto.setName(jsonObject.getString("name"));
        materialDto.setCode(jsonObject.getString("code"));
        materialDto.setMaterial(jsonObject.getString("material"));
        materialDto.setSpec(jsonObject.getString("spec"));
        materialDto.setLength(jsonObject.getDouble("length"));
        materialDto.setDiameter(jsonObject.getDouble("diameter"));
        materialDto.setWallThickness(jsonObject.getInteger("wallThickness"));
        materialDto.setManufacturer(jsonObject.getString("manufacturer"));
        materialDto.setManufactureAddr(jsonObject.getString("manufactureAddr"));
        materialDto.setManufactureDate(jsonObject.getDate("manufactureDate"));
        materialDto.setBatchNum(jsonObject.getString("batchNum"));
        materialDto.setCompanyId(orgService.getReginParams().getBusinessInfo().getCompanySequenceNbr());
        materialDto.setType(jsonObject.getString("type"));
        MaterialDto result = this.createWithModel(materialDto);
        return result;
    }
    /**
     * 修改材料+附件信息
     * @param sequenceNbr
     * @param jsonObject
     */
    public void updateMI(Long sequenceNbr,JSONObject jsonObject){

        MaterialDto materialDto = this.queryBySeq(sequenceNbr);
        LambdaQueryWrapper<Attachment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Attachment::getSourceId,sequenceNbr);
        Attachment attachment = attachmentServiceImpl.getOne(wrapper);
        materialDto.setName(jsonObject.getString("name"));
        materialDto.setCode(jsonObject.getString("code"));
        materialDto.setMaterial(jsonObject.getString("material"));
        materialDto.setSpec(jsonObject.getString("spec"));
        materialDto.setLength(jsonObject.getDouble("length"));
        materialDto.setDiameter(jsonObject.getDouble("diameter"));
        materialDto.setWallThickness(jsonObject.getInteger("wallThickness"));
        materialDto.setManufacturer(jsonObject.getString("manufacturer"));
        materialDto.setManufactureAddr(jsonObject.getString("manufactureAddr"));
        materialDto.setManufactureDate(jsonObject.getDate("manufactureDate"));
        materialDto.setBatchNum(jsonObject.getString("batchNum"));
        materialDto.setType(jsonObject.getString("type"));
        this.updateWithModel(materialDto);
        JSONArray subForm = jsonObject.getJSONArray("subForm");
        if(!ValidationUtil.isEmpty(subForm)){
            if(ValidationUtil.isEmpty(attachment)){
                attachmentServiceImpl.saveAttachment(subForm,sequenceNbr);
            }else {
                attachment.setInfo(JSON.toJSONString(subForm));
                attachmentServiceImpl.updateById(attachment);
            }
        }
    }
    /**
     * 根据sequenceNbr查询材料的附件
     *
     * @param sequenceNbr  主键
     * @return
     */
    public JSONObject groupBySeq(Long sequenceNbr){
        MaterialDto materialDto = queryBySeq(sequenceNbr);
        AttachmentDto attachmentDto = attachmentMapper.selectAttBySeq(sequenceNbr);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("name",materialDto.getName());
        jsonObject.put("code",materialDto.getCode());
        jsonObject.put("material",materialDto.getMaterial());
        jsonObject.put("spec",materialDto.getSpec());
        jsonObject.put("length",materialDto.getLength());
        jsonObject.put("diameter",materialDto.getDiameter());
        jsonObject.put("wallThickness",materialDto.getWallThickness());
        jsonObject.put("manufacturer",materialDto.getManufacturer());
        jsonObject.put("manufactureAddr",materialDto.getManufactureAddr());
        jsonObject.put("manufactureDate",materialDto.getManufactureDate());
        jsonObject.put("batchNum",materialDto.getBatchNum());
        jsonObject.put("type",materialDto.getType());
        if (attachmentDto != null){
            JSONArray jsonArray = JSON.parseArray(attachmentDto.getInfo());
            jsonObject.put("subForm",jsonArray);
        }
        return jsonObject;
    }

    // 根据管材编号查询管材(管材编号必须唯一,报错一因为脏数据管材编号不唯一)
    public Material getMaterial(String  code){
        LambdaQueryWrapper<Material> wrapper = new LambdaQueryWrapper<>( );
        wrapper.eq(Material ::getCode,code);
        Material material = materialMapper.selectOne(wrapper);
        return material;
    }




    @BusinessIdentify
    public List<MaterialCount> pipeManufacturerStatistics() {
        List<MaterialCount> materialCountList=null;
        Long companySequenceNbr = orgService.getReginParams().getBusinessInfo().getCompanySequenceNbr();
        ArrayList<Long> listIdList = Lists.newArrayList();
        listIdList.add(companySequenceNbr);
        LambdaQueryWrapper<SuperviseRule> wrapper = new LambdaQueryWrapper<>();
        String type = companyMapper.selectById(companySequenceNbr).getType();
        if (!ValidationUtil.isEmpty(type)) {
            if (type.contains(OrgEnum.监检机构.getKey())){
                wrapper.eq(SuperviseRule::getInspectionUnitId,companySequenceNbr);
                List<SuperviseRule> superviseRules = superviseRuleMapper.selectList(wrapper);
                for (SuperviseRule i:superviseRules){
                    LambdaQueryWrapper<Company> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(Company::getRegionCode,i.getAdminRegionCode());
                    List<Company> companies = companyMapper.selectList(lambdaQueryWrapper);
                    for (Company company : companies) {
                        listIdList.add(company.getSequenceNbr());
                    }
                }

            }else if (type.contains(OrgEnum.监察部门.getKey())) {
                wrapper.eq(SuperviseRule::getSuperviseDeptId,companySequenceNbr);
                List<SuperviseRule> superviseRules = superviseRuleMapper.selectList(wrapper);
                for (SuperviseRule i:superviseRules){
                    LambdaQueryWrapper<Company> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(Company::getRegionCode,i.getAdminRegionCode());
                    List<Company> companies = companyMapper.selectList(lambdaQueryWrapper);
                    for (Company company : companies) {
                        listIdList.add(company.getSequenceNbr());
                    }
                }
            }
            materialCountList =materialMapper.getConditionCount(listIdList);
        }

        return materialCountList;
    }


}