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

import static org.hamcrest.CoreMatchers.nullValue;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import javax.annotation.Resource;

import com.yeejoin.amos.boot.biz.common.utils.Menu;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.annotation.Condition;
import org.typroject.tyboot.core.rdbms.annotation.Operator;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

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.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.constants.BizConstant;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.biz.common.utils.EnumsUtils;
import com.yeejoin.amos.boot.module.common.api.dto.RequestData;
import com.yeejoin.amos.boot.module.common.api.dto.WaterResourceCraneDto;
import com.yeejoin.amos.boot.module.common.api.dto.WaterResourceDto;
import com.yeejoin.amos.boot.module.common.api.dto.WaterResourceHydrantDto;
import com.yeejoin.amos.boot.module.common.api.dto.WaterResourceNaturalDto;
import com.yeejoin.amos.boot.module.common.api.dto.WaterResourcePoolDto;
import com.yeejoin.amos.boot.module.common.api.dto.WaterResourceTypeDto;
import com.yeejoin.amos.boot.module.common.api.dto.WaterResourceZhDto;
import com.yeejoin.amos.boot.module.common.api.entity.WaterResource;
import com.yeejoin.amos.boot.module.common.api.entity.WaterResourceCrane;
import com.yeejoin.amos.boot.module.common.api.entity.WaterResourceHydrant;
import com.yeejoin.amos.boot.module.common.api.entity.WaterResourceIndex;
import com.yeejoin.amos.boot.module.common.api.entity.WaterResourceNatural;
import com.yeejoin.amos.boot.module.common.api.entity.WaterResourcePool;
import com.yeejoin.amos.boot.module.common.api.enums.WaterResourceTypeEnum;
import com.yeejoin.amos.boot.module.common.api.feign.EquipFeignClient;
import com.yeejoin.amos.boot.module.common.api.mapper.WaterResourceMapper;
import com.yeejoin.amos.boot.module.common.api.service.IWaterResourceService;

/**
 * 服务实现类
 *
 * @author system_generator
 * @date 2021-06-29
 */
@Service
public class WaterResourceServiceImpl extends BaseService<WaterResourceDto, WaterResource, WaterResourceMapper> implements IWaterResourceService {

    @Autowired
    WaterResourceCraneServiceImpl waterResourceCraneService;
    @Autowired
    WaterResourceHydrantServiceImpl waterResourceHydrantService;
    @Autowired
    WaterResourceNaturalServiceImpl waterResourceNaturalService;
    @Autowired
    WaterResourcePoolServiceImpl waterResourcePoolService;
    @Autowired
    WaterResourceIotServiceImpl waterResourceIotService;
    @Resource
    WaterResourceMapper waterResourceMapper;
    @Autowired
    WaterResourceIndexServiceImpl waterResourceIndexServiceImpl;
    
    @Autowired
    DataDictionaryServiceImpl dataDictionaryService;
    @Autowired
    EquipFeignClient equipFeignClient;
    /**
     * 分页查询
     */
    public Page<WaterResourceDto> queryForWaterResourcePage(Page<WaterResourceDto> page,
                                                            @Condition(Operator.like) String name,
                                                            @Condition(Operator.eq) String resourceType,
                                                            @Condition(Operator.in) ArrayList<Long> belongBuildingId,
                                                            @Condition(Operator.eq) Long belongFightingSystemId,
                                                            @Condition(Operator.eq) Long sequenceNbr,
                                                            String equipId,
                                                            String bizOrgCode) {
        return this.waterResourceMapper.getWaterResourcePageByParams(page, name, resourceType, belongBuildingId,
                belongFightingSystemId, sequenceNbr, equipId,bizOrgCode);
    }

    /**
     * 列表查询 示例
     */
    public List<WaterResourceDto> queryForWaterResourceList(@Condition(Operator.eq) Boolean isDelete) {
        return this.queryForList("", false, isDelete);
    }

    /**
     * 列表条件查询
     */
    public List<WaterResourceDto> queryWaterResourceList(@Condition(Operator.eq) Boolean isDelete,
                                                         @Condition(Operator.like) String name,
                                                         @Condition(Operator.eq) Long sequenceNbr,
                                                         @Condition(Operator.eq) Long belongFightingSystemId,
                                                         @Condition(Operator.eq) Long belongBuildingId,
                                                         @Condition(Operator.like) String belongBuilding,
                                                         @Condition(Operator.eq) String resourceType) {
        return this.queryForList("", false, isDelete, name, sequenceNbr, belongFightingSystemId, belongBuildingId,
                belongBuilding, resourceType);
    }


    /**
     * excel导入
     *
     * @param model
     * @return
     */
    public WaterResourceDto importByExcel(WaterResourceDto model) {
        String resourceType = model.getResourceType();
        Optional<WaterResourceTypeEnum> resourceTypeEnum = EnumsUtils.getEnumObject(WaterResourceTypeEnum.class,
                e -> e.getCode().equals(resourceType));
        model.setResourceTypeName(resourceTypeEnum.get().getName());
        model.setRealityImg(JSONArray.toJSONString(model.getRealityImgList()));
        model.setOrientationImg(JSONArray.toJSONString(model.getOrientationImgList()));
        if (!StringUtils.isEmpty(resourceType)) {
            switch (resourceType) {
                case "hydrant":
                    // 新增基础信息
                    model.setIsIot(true);
                    createWithModel(model);
                    // 新增属性信息
                    WaterResourceHydrantDto waterResourceHydrantDto = new WaterResourceHydrantDto();
                    BeanUtils.copyProperties(model, waterResourceHydrantDto);
                    waterResourceHydrantDto.setSequenceNbr(null);
                    waterResourceHydrantDto.setResourceId(model.getSequenceNbr());
                    waterResourceHydrantService.createWithModel(waterResourceHydrantDto);
                    break;
                case "crane":
                    // 新增基础信息
                    model.setIsIot(true);
                    createWithModel(model);
                    WaterResourceCraneDto waterResourceCraneDto = new WaterResourceCraneDto();
                    BeanUtils.copyProperties(model, waterResourceCraneDto);
                    waterResourceCraneDto.setSequenceNbr(null);
                    waterResourceCraneDto.setResourceId(model.getSequenceNbr());
                    waterResourceCraneService.createWithModel(waterResourceCraneDto);
                    break;
                case "natural":
                    // 新增基础信息
                    model.setIsIot(false);
                    createWithModel(model);
                    WaterResourceNaturalDto waterResourceNaturalDto = new WaterResourceNaturalDto();
                    BeanUtils.copyProperties(model, waterResourceNaturalDto);
                    waterResourceNaturalDto.setSequenceNbr(null);
                    waterResourceNaturalDto.setResourceId(model.getSequenceNbr());
                    waterResourceNaturalService.createWithModel(waterResourceNaturalDto);
                    break;
                case "pool":
                    // 新增基础信息
                    model.setIsIot(true);
                    createWithModel(model);
                    WaterResourcePoolDto waterResourcePoolDto = new WaterResourcePoolDto();
                    BeanUtils.copyProperties(model, waterResourcePoolDto);
                    waterResourcePoolDto.setSequenceNbr(null);
                    waterResourcePoolDto.setResourceId(model.getSequenceNbr());
                    waterResourcePoolService.createWithModel(waterResourcePoolDto);
                    break;
            }
            // 新增物联信息
//            if (model.getIsIot()) {
//                WaterResourceIotDto waterResourceIotDto = new WaterResourceIotDto();
//                BeanUtils.copyProperties(model, waterResourceIotDto);
//                waterResourceIotDto.setSequenceNbr(null);
//                waterResourceIotDto.setResourceType(model.getResourceType());
//                waterResourceIotDto.setResourceId(model.getSequenceNbr());
//                waterResourceIotService.createWithModel(waterResourceIotDto);
//            }
        } else {
            createWithModel(model);
        }
        return model;
    }

    /**
     * 导出列表
     */
    public List<WaterResourceDto> exportToExcel(Boolean isDelete,String name,
                                                String resourceType) {
        return waterResourceMapper.exportToExcel(isDelete,name,resourceType);
    }

    @Override
    public List<WaterResourceZhDto> getWaterResourceList(Integer pageNum, Integer pageSize, RequestData requestData) {
        if (null == pageNum || null == pageSize) {
            pageNum = 1;
            pageSize = Integer.MAX_VALUE;
        } else {
            pageNum = (pageNum - 1) * pageSize;
        }
        return waterResourceMapper.getWaterResourceList(pageNum, pageSize, requestData);
    }

    @Override
    public Integer getWaterResourceListCount(RequestData requestData) {
        return waterResourceMapper.getWaterResourceListCount(requestData);
    }

    @Override
    public WaterResourceDto selectBySequenceNbr(Long sequenceNbr) {
        // 查询基本信息
        WaterResourceDto waterResourceDto = this.queryBySeq(sequenceNbr);
        waterResourceDto.setRealityImgList(JSONArray.parseArray(waterResourceDto.getRealityImg(), Object.class));
        waterResourceDto.setOrientationImgList(JSONArray.parseArray(waterResourceDto.getOrientationImg()));

        if(ValidationUtil.isEmpty(waterResourceDto.getContactUser())) {
            waterResourceDto.setContactUser("");
        }

        if(ValidationUtil.isEmpty(waterResourceDto.getContactPhone())) {
            waterResourceDto.setContactPhone("");
        }

        if(ValidationUtil.isEmpty(waterResourceDto.getManagementUnit())) {
            waterResourceDto.setManagementUnit("");
        }

        if(ValidationUtil.isEmpty(waterResourceDto.getSection())) {
            waterResourceDto.setSection("");
        }


        if(ValidationUtil.isEmpty(waterResourceDto.getWaterSupplyName())) {
            waterResourceDto.setWaterSupplyName("");
        }

        Boolean isDelete = waterResourceDto.getIsDelete();
        // 查询属性信息
        String resourceType = waterResourceDto.getResourceType();
        if (!StringUtils.isEmpty(resourceType)) {
            switch (resourceType) {
                case "hydrant":
                    WaterResourceHydrant waterResourceHydrant =
                            waterResourceHydrantService.getOne(new QueryWrapper<WaterResourceHydrant>().eq(
                                    "resource_id",
                                    sequenceNbr));
                    if(null != waterResourceHydrant) {
                        BeanUtils.copyProperties(waterResourceHydrant, waterResourceDto);
                    }
                    break;
                case "crane":
                    WaterResourceCrane waterResourceCrane =
                            waterResourceCraneService.getOne(new QueryWrapper<WaterResourceCrane>().eq("resource_id",
                                    sequenceNbr));
                    if(null != waterResourceCrane) {
                        BeanUtils.copyProperties(waterResourceCrane, waterResourceDto);
                    }
                    break;
                case "natural":
                    WaterResourceNatural waterResourceNatural =
                            waterResourceNaturalService.getOne(new QueryWrapper<WaterResourceNatural>().eq(
                                    "resource_id",
                                    sequenceNbr));
                    if(null != waterResourceNatural) {
                        BeanUtils.copyProperties(waterResourceNatural, waterResourceDto);
                    }

                    break;
                case "pool":
                    WaterResourcePool waterResourcePool =
                            waterResourcePoolService.getOne(new QueryWrapper<WaterResourcePool>().eq("resource_id",
                                    sequenceNbr));
                    if(null != waterResourcePool) {
                        BeanUtils.copyProperties(waterResourcePool, waterResourceDto);
                    }
                    break;
            }
        }
        waterResourceDto.setSequenceNbr(sequenceNbr);
        waterResourceDto.setIsDelete(isDelete);
        // 查询物联参数
        LambdaQueryWrapper<WaterResourceIndex> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WaterResourceIndex::getWaterId,waterResourceDto.getSequenceNbr());
        List<WaterResourceIndex> list = waterResourceIndexServiceImpl.list(queryWrapper);
        if(list.size()>0) {
            Map<String,Object> map = new HashMap<>();
            list.stream().forEach(e->{
                map.put(e.getNameKey(),e.getPerfValue());
            });
            waterResourceDto.setWaterResourceIotDto(map);
        }
        return waterResourceDto;
    }

    public List<WaterResourceTypeDto> getWaterResourceTypeList(Boolean isDelete) {
        return waterResourceMapper.getWaterResourceTypeList(isDelete);
    }

    public static JSONObject getLongLatFromAddress(String address) {
        JSONObject result = new JSONObject();
        result.put(BizConstant.ADDRESS, "");
        result.put(BizConstant.LONGITUDE, "0");
        result.put(BizConstant.LATITUDE, "0");
        if (StringUtils.isNotEmpty(address)) {
            String[] addressData = address.split("@address@");
            if (addressData.length > 1) {
                result.put(BizConstant.ADDRESS, addressData[0]);
                JSONObject langLatObj = JSON.parseObject(addressData[1]);
                if (StringUtils.isNotEmpty(langLatObj.getString(BizConstant.LONGITUDE))) {
                    result.put(BizConstant.LONGITUDE, langLatObj.getString(BizConstant.LONGITUDE));
                } else {
                    result.put(BizConstant.LONGITUDE, "0");
                }
                if (StringUtils.isNotEmpty(langLatObj.getString(BizConstant.LATITUDE))) {
                    result.put(BizConstant.LATITUDE, langLatObj.getString(BizConstant.LATITUDE));
                } else {
                    result.put(BizConstant.LATITUDE, "0");
                }
            } else {
                result.put(BizConstant.ADDRESS, addressData[0]);
            }
        }
        return result;
    }

	public List<Menu> getwaterResourceTypeTree(String bizOrgCode) throws Exception {
        List<Menu> list  = new ArrayList<>();
		ResponseModel <Object>  response= 	equipFeignClient.list();
		if(response.getStatus() != 200) {
			return null;
		}
		Object resultObject =	response.getResult();
		JSONArray childrenArray = null;
		JSONArray waterTypeDetailArray = null;
		JSONObject waterTypeDetailJson=null;
		JSONArray resultArray =	JSONArray.parseArray(JSONArray.toJSONString(resultObject));
		for (Object obj : resultArray) {
			JSONObject detailJsonObject=	JSONObject.parseObject(JSONObject.toJSONString(obj));
			String codeString =	detailJsonObject.getString("code");
			if(codeString.equals("90000000")) {
				childrenArray = detailJsonObject.getJSONArray("children");
				break;
			}
		}
		if(childrenArray!=null && childrenArray.size()>0) {
			for (Object childObject : childrenArray) {
				JSONObject detailChildJsonObject=	JSONObject.parseObject(JSONObject.toJSONString(childObject));
				String codeStr =	detailChildJsonObject.getString("code");
				if(codeStr.equals("93000000")) {
					waterTypeDetailArray=detailChildJsonObject.getJSONArray("children");
					break;
				}
			}
			
		}
		if(waterTypeDetailArray!=null && waterTypeDetailArray.size()>0) {
			for (Object childObject : waterTypeDetailArray) {
				JSONObject waterTypeDetail=	JSONObject.parseObject(JSONObject.toJSONString(childObject));
				String codeStr =	waterTypeDetail.getString("code");
				if(codeStr.equals("93060000")) {
					waterTypeDetailJson =	waterTypeDetail;
					break;
				}
			}
		}
		if(waterTypeDetailJson!=null) {
			Map<String, Object>  map=	waterResourceMapper.getWaterTypeByBizOrgCode(bizOrgCode);
			int num=0;
			JSONArray waterTypeDetailChildrenArray = waterTypeDetailJson.getJSONArray("children");
			JSONArray array = new JSONArray();
			for (Object childObject : waterTypeDetailChildrenArray) {

				JSONObject detail=	JSONObject.parseObject(JSONObject.toJSONString(childObject));
				String codeStr =	detail.getString("code");
				if(map!=null && map.containsKey(codeStr)) {
					num=num+Integer.parseInt( map.get("codeStr").toString());
					detail.put("num", Integer.parseInt( map.get("codeStr").toString()));
				}else {
					detail.put("num", 0);
				}
                Menu menu = new Menu(Long.valueOf(detail.get("id").toString()) ,detail.get("name").toString(),null,Integer.parseInt(detail.get("num").toString()));
                list.add(menu);

//				if (detail.get("children").toString().length() == 2) {
//                    detail.put("children",null);
//                }
//				array.add(detail);
			}
//			waterTypeDetailJson.remove("children");
//            if(array.size() == 0) {
//                waterTypeDetailJson.put("children", null);
//            } else {
//                waterTypeDetailJson.put("children", array);
//            }
//			waterTypeDetailJson.put("num", num);
		}
		return	list;
	}
	public Object getwaterResourceType() throws Exception {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		ResponseModel <Object>  response= 	equipFeignClient.list();
		if(response.getStatus() != 200) {
			return null;
		}
		Object resultObject =	response.getResult();
		JSONArray childrenArray = null;
		JSONArray waterTypeDetailArray = null;
		JSONObject waterTypeDetailJson=null;
		JSONArray resultArray =	JSONArray.parseArray(JSONArray.toJSONString(resultObject));
		for (Object obj : resultArray) {
			JSONObject detailJsonObject=	JSONObject.parseObject(JSONObject.toJSONString(obj));
			String codeString =	detailJsonObject.getString("code");
			if(codeString.equals("90000000")) {
				childrenArray = detailJsonObject.getJSONArray("children");
				break;
			}
		}
		if(childrenArray!=null && childrenArray.size()>0) {
			for (Object childObject : childrenArray) {
				JSONObject detailChildJsonObject=	JSONObject.parseObject(JSONObject.toJSONString(childObject));
				String codeStr =	detailChildJsonObject.getString("code");
				if(codeStr.equals("93000000")) {
					waterTypeDetailArray=detailChildJsonObject.getJSONArray("children");
					break;
				}
			}
			
		}
		if(waterTypeDetailArray!=null && waterTypeDetailArray.size()>0) {
			for (Object childObject : waterTypeDetailArray) {
				JSONObject waterTypeDetail=	JSONObject.parseObject(JSONObject.toJSONString(childObject));
				String codeStr =	waterTypeDetail.getString("code");
				if(codeStr.equals("93060000")) {
					waterTypeDetailJson =	waterTypeDetail;
					break;
				}
			}
		}
		if(waterTypeDetailJson!=null) {
			JSONArray waterTypeDetailChildrenArray = waterTypeDetailJson.getJSONArray("children");
			
			for (Object childObject : waterTypeDetailChildrenArray) {
				Map<String, Object> map = new LinkedHashMap<>();
				JSONObject detail=	JSONObject.parseObject(JSONObject.toJSONString(childObject));
				String codeStr =	detail.getString("code");
				String name =	detail.getString("name");
				map.put("code", codeStr);
				map.put("name", name);
				list.add(map);
			}
		}
		return	list;
	}
}
