package com.yeejoin.amos.boot.module.tzs.biz.controller;

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.yeejoin.amos.boot.biz.common.controller.BaseController;
import com.yeejoin.amos.boot.biz.common.feign.AmosFeignService;
import com.yeejoin.amos.boot.biz.common.utils.NameUtils;
import com.yeejoin.amos.boot.module.common.api.feign.EquipFeignClient;
import com.yeejoin.amos.boot.module.tzs.api.dto.AlertMsgDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.AlertPaperInfoDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.ESAlertCalledDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.ElevatorBaseInfoDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.ElevatorDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.ElevatorInfoDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.ElevatorListDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.ElevatorMaintenanceInfoDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.ElevatorNewDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.ElevatorTestInfoDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.ElevatorWlInfoDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.EsElevatorDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.EsSpecialEquipmentDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.EsSpecialEquipmentListDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.SpecialEquipmentDto;
import com.yeejoin.amos.boot.module.tzs.api.entity.Elevator;
import com.yeejoin.amos.boot.module.tzs.api.entity.EquipmentRegionNum;
import com.yeejoin.amos.boot.module.tzs.api.entity.MaintainInfo;
import com.yeejoin.amos.boot.module.tzs.api.entity.TestInfo;
import com.yeejoin.amos.boot.module.tzs.api.enums.SpecialEquipmentCategoryEnum;
import com.yeejoin.amos.boot.module.tzs.api.service.IElevatorRelationService;
import com.yeejoin.amos.boot.module.tzs.api.service.IElevatorService;
import com.yeejoin.amos.boot.module.tzs.api.service.TzsAuthService;
import com.yeejoin.amos.boot.module.tzs.biz.service.impl.ESCylinderServiceImpl;
import com.yeejoin.amos.boot.module.tzs.biz.service.impl.ESElevatorServiceImpl;
import com.yeejoin.amos.boot.module.tzs.biz.service.impl.ElevatorServiceImpl;
import com.yeejoin.amos.boot.module.tzs.biz.service.impl.EquipmentRegionNumServiceImpl;
import com.yeejoin.amos.boot.module.tzs.biz.service.impl.MaintainInfoServiceImpl;
import com.yeejoin.amos.boot.module.tzs.biz.service.impl.MsgLogServiceImpl;
import com.yeejoin.amos.boot.module.tzs.biz.service.impl.TestInfoServiceImpl;
import com.yeejoin.amos.boot.module.tzs.biz.utils.BeanDtoVoUtils;
import com.yeejoin.amos.boot.module.tzs.flc.api.dto.CylinderInfoDto;
import com.yeejoin.amos.boot.module.tzs.flc.api.entity.CylinderInfo;
import com.yeejoin.amos.boot.module.tzs.flc.api.mapper.CylinderInfoMapper;
import com.yeejoin.amos.boot.module.tzs.flc.biz.service.impl.CylinderInfoServiceImpl;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.DictionarieValueModel;
import com.yeejoin.amos.feign.systemctl.model.RegionModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javafx.scene.shape.Cylinder;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.typroject.tyboot.component.emq.EmqKeeper;
import org.typroject.tyboot.core.foundation.enumeration.UserType;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.doc.TycloudOperation;
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.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 特种设备API
 */
@RestController
@Api(tags = "特种设备API")
@RequestMapping(value = "/special-equipment")
public class SpecialEquipmentController extends BaseController {

    private final Logger logger = LoggerFactory.getLogger(SpecialEquipmentController.class);

    @Autowired
    IElevatorService iElevatorService;

    @Autowired
    ElevatorServiceImpl elevatorService;

    @Autowired
    private AmosFeignService amosFeignService;
    @Autowired
    private MaintainInfoServiceImpl maintainInfoService;
	 @Autowired
	private EquipFeignClient equipFeignClient;
    @Autowired
    private TestInfoServiceImpl testInfoService;

    @Autowired
    ESElevatorServiceImpl esElevatorService;

    @Autowired
    private EmqKeeper emqKeeper;

    @Value("${mqtt.topic.elevator.push}")
    private String elevatorpushTopic;

    @Autowired
    private IElevatorRelationService elevatorRelationService;

    @Autowired
    TzsAuthService tzsAuthService;

    @Autowired
    EquipmentRegionNumServiceImpl equipmentRegionNumServiceImpl;

    @Autowired
    ESCylinderServiceImpl esCylinderService;

    @Autowired
    CylinderInfoMapper cylinderInfoMapper;

    @Autowired
    MsgLogServiceImpl msgLogService;

    /**
     * ES查询特种设备信息    带分页    加经纬度过滤 keyword 搜索
     *
     * @return 查询结果
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @RequestMapping(value = "/querySpecialEquipmentListPage", method = RequestMethod.POST)
    @ApiOperation(httpMethod = "POST", value = "ES查询特种设备信息带分页 ", notes = "ES查询特种设备信息带分页")
    public ResponseModel<Page<SpecialEquipmentDto>> querySpecialEquipmentListPage(@RequestBody EsSpecialEquipmentDto esSpecialEquipmentDto
            , @RequestParam(value = "current") int current, @RequestParam(value = "size") int size){
        Page<SpecialEquipmentDto> result = null;
        if (ValidationUtil.isEmpty(esSpecialEquipmentDto.getCategoryCode())) {
            throw new BadRequest("参数校验失败.");
        }
        if(StringUtils.isNotBlank(esSpecialEquipmentDto.getCategoryCode())) { // 查找特定设备
            if(SpecialEquipmentCategoryEnum.ELEVATOR.getCode().equals(esSpecialEquipmentDto.getCategoryCode())) {
                result = esElevatorService.queryPageByDto(esSpecialEquipmentDto, current, size);
            }
            if(SpecialEquipmentCategoryEnum.PRESSURE_VESSEL.getCode().equals(esSpecialEquipmentDto.getCategoryCode())) {
                result = esCylinderService.queryPageByDto(esSpecialEquipmentDto, current, size);
            }
        }
        return ResponseHelper.buildResponse(result);
    }


    /**
     * ES查询特种设备信息    不带分页   加经纬度过滤  keyword 搜索
     *
     * @return 查询结果
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @RequestMapping(value = "/querySpecialEquipmentList", method = RequestMethod.POST)
    @ApiOperation(httpMethod = "POST", value = "ES查询特种设备信息不带分页", notes = "ES查询特种设备信息不带分页")
    public ResponseModel<List<SpecialEquipmentDto>> querySpecialEquipmentList(@RequestBody EsSpecialEquipmentDto esSpecialEquipmentDto){
        List<SpecialEquipmentDto> result = new ArrayList<>();
        if (ValidationUtil.isEmpty(esSpecialEquipmentDto.getCategoryCode())) {
            throw new BadRequest("参数校验失败.");
        }
        if(StringUtils.isNotBlank(esSpecialEquipmentDto.getCategoryCode())) { // 查找特定设备
            if(SpecialEquipmentCategoryEnum.ELEVATOR.getCode().equals(esSpecialEquipmentDto.getCategoryCode())) {
                result = esElevatorService.queryByDto(esSpecialEquipmentDto);
            }
            if(SpecialEquipmentCategoryEnum.PRESSURE_VESSEL.getCode().equals(esSpecialEquipmentDto.getCategoryCode())) {
                result = esCylinderService.queryByDto(esSpecialEquipmentDto);
            }
        }
        return ResponseHelper.buildResponse(result);
    }

    /**
     * ES查询特种设备聚合信息
     *
     * @return 查询结果
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @RequestMapping(value = "/queryTogetherByDto", method = RequestMethod.POST)
    @ApiOperation(httpMethod = "POST", value = "ES查询聚合信息", notes = "ES查询聚合信息")
    public ResponseModel<List<Map<String, String>>> queryTogetherByDto(@RequestBody EsSpecialEquipmentDto esSpecialEquipmentDto){
        List<Map<String, String>> result = new ArrayList<>();
        if (ValidationUtil.isEmpty(esSpecialEquipmentDto.getCategoryCode()) ||
                ValidationUtil.isEmpty(esSpecialEquipmentDto.getPrecision())  ||
                ValidationUtil.isEmpty(esSpecialEquipmentDto.getStartLatitude()) ||
                ValidationUtil.isEmpty(esSpecialEquipmentDto.getStartLongitude()) ||
                ValidationUtil.isEmpty(esSpecialEquipmentDto.getEndLatitude()) ||
                ValidationUtil.isEmpty(esSpecialEquipmentDto.getEndLongitude())) {
            throw new BadRequest("参数校验失败.");
        }
        if(StringUtils.isNotBlank(esSpecialEquipmentDto.getCategoryCode())) { // 查找特定设备
            if("3000".equals(esSpecialEquipmentDto.getCategoryCode())) {
                result = esElevatorService.queryTogetherByDto(esSpecialEquipmentDto);
            }
        }
        return ResponseHelper.buildResponse(result);
    }


    /***
     * keyword 区域 查询八大类总数
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @RequestMapping(value = "/queryEquipNum", method = RequestMethod.POST)
    @ApiOperation(httpMethod = "POST", value = "查询八大类总数", notes = "查询八大类总数")
    public ResponseModel<Map<String, Long>> queryEquipNum(@RequestBody EsSpecialEquipmentDto esSpecialEquipmentDto){
        Map<String, Long> result = new HashMap<>();
        //  锅炉
        Long boiler = 0L;
        result.put("1000",boiler);
        // 压力容器
        Long vessel = esCylinderService.queryNumberByDto(esSpecialEquipmentDto);
        result.put("2000",vessel);
        // 电梯
        Long elevator = esElevatorService.queryNumberByDto(esSpecialEquipmentDto);
        result.put("3000",elevator);
        // 起重机械
        Long crane = 0L;
        result.put("4000",crane);
        // 大型游乐设施
        Long facility = 0L;
        result.put("6000",facility);

        return ResponseHelper.buildResponse(result);
    }



    /***
     * 查询八大类聚合总数
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @RequestMapping(value = "/queryEquipNumByType", method = RequestMethod.POST)
    @ApiOperation(httpMethod = "POST", value = "查询八大类聚合总数", notes = "查询八大类聚合总数")
    public ResponseModel<List<Map<String, String>>> queryEquipNumByType(@RequestBody EsSpecialEquipmentDto esSpecialEquipmentDto){
        if (ValidationUtil.isEmpty(esSpecialEquipmentDto.getSelectType()) || ValidationUtil.isEmpty(esSpecialEquipmentDto.getCategoryCode())) {
            throw new BadRequest("参数校验失败.");
        }
        List<Map<String, String>> result = new ArrayList<>();
        List<RegionModel> userTree = tzsAuthService.getUserReginTree();
        // 树为省市县
        RegionModel province = userTree.get(0);
        if("0".equals(esSpecialEquipmentDto.getSelectType())) { // 获取省聚合
            List<EquipmentRegionNum> list = equipmentRegionNumServiceImpl.list(new LambdaQueryWrapper<EquipmentRegionNum>().eq(EquipmentRegionNum::getProvinceCode,province.getRegionCode()).eq(EquipmentRegionNum::getCategoryCode,esSpecialEquipmentDto.getCategoryCode()));
            Long count = 0L;
            for(EquipmentRegionNum t : list) {
                count += t.getNum();
            }
            Map<String, String> tepMap = new HashMap<>();
            tepMap.put("number",count+"");
            tepMap.put("lat",province.getLatitude());
            tepMap.put("lon",province.getLongitude());
            tepMap.put("label",province.getRegionName());
            result.add(tepMap);
        } else if("1".equals(esSpecialEquipmentDto.getSelectType())) {// 获取市聚合
            List<RegionModel> citys = (List<RegionModel>) province.getChildren();
            citys.forEach(c -> {
                List<EquipmentRegionNum> list = equipmentRegionNumServiceImpl.list(new LambdaQueryWrapper<EquipmentRegionNum>().eq(EquipmentRegionNum::getCityCode,c.getRegionCode()).eq(EquipmentRegionNum::getCategoryCode,esSpecialEquipmentDto.getCategoryCode()));
                Long count = 0L;
                for(EquipmentRegionNum t : list) {
                    count += t.getNum();
                }
                Map<String, String> tepMap = new HashMap<>();
                tepMap.put("number",count+"");
                tepMap.put("lat",c.getLatitude());
                tepMap.put("lon",c.getLongitude());
                tepMap.put("label",c.getRegionName());
                result.add(tepMap);
             });
        } else if("2".equals(esSpecialEquipmentDto.getSelectType())) {// 获取县聚合
            List<RegionModel> citys = (List<RegionModel>) province.getChildren();
            citys.forEach(c -> {
                List<RegionModel> districts = (List<RegionModel>) c.getChildren();
                districts.forEach(d -> {
                    List<EquipmentRegionNum> list = equipmentRegionNumServiceImpl.list(new LambdaQueryWrapper<EquipmentRegionNum>().eq(EquipmentRegionNum::getDistrictCode,d.getRegionCode()).eq(EquipmentRegionNum::getCategoryCode,esSpecialEquipmentDto.getCategoryCode()));
                    Long count = 0L;
                    for(EquipmentRegionNum t : list) {
                        count += t.getNum();
                    }
                    Map<String, String> tepMap = new HashMap<>();
                    tepMap.put("number",count+"");
                    tepMap.put("lat",d.getLatitude());
                    tepMap.put("lon",d.getLongitude());
                    tepMap.put("label",d.getRegionName());
                    result.add(tepMap);
                });
            });
        }
        return ResponseHelper.buildResponse(result);
    }


    /***
     * 初始化设备
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @RequestMapping(value = "/initEquipment", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "初始化设备", notes = "初始化设备")
    public void initEquipment(Integer num){
        IPage<Elevator> elevatorPage = new Page<>();
        List<RegionModel> tree = (List<RegionModel>) Systemctl.regionClient.queryForTree(null).getResult();
        // 按照最低级来查询数量 保存地址
        RegionModel start = tree.get(0); // 省
        List<RegionModel> city = (List<RegionModel>) start.getChildren();
        city.forEach(c -> {
            List<RegionModel> district = (List<RegionModel>) c.getChildren();
            district.forEach(d -> {
                List<Elevator> list = elevatorService.list(new LambdaQueryWrapper<Elevator>().eq(Elevator::getIsDelete,false).like(Elevator::getRegionCode,d.getRegionCode()));
                EquipmentRegionNum temp = new EquipmentRegionNum();
                temp.setCategoryCode("3000");
                temp.setCityCode(c.getRegionCode()+"");
                temp.setDistrictCode(d.getRegionCode()+"");
                temp.setProvinceCode(start.getRegionCode()+"");
                temp.setLatitude(d.getLatitude());
                temp.setLongitude(d.getLongitude());
                temp.setNum((long) list.size());
                equipmentRegionNumServiceImpl.save(temp);

                List<CylinderInfoDto> cylinderInfoList =
                        cylinderInfoMapper.listWithRegionCode(d.getRegionCode());
                EquipmentRegionNum temp1 = new EquipmentRegionNum();
                temp1.setCategoryCode("2000");
                temp1.setCityCode(c.getRegionCode()+"");
                temp1.setDistrictCode(d.getRegionCode()+"");
                temp1.setProvinceCode(start.getRegionCode()+"");
                temp1.setLatitude(d.getLatitude());
                temp1.setLongitude(d.getLongitude());
                temp1.setNum((long) cylinderInfoList.size());
                equipmentRegionNumServiceImpl.save(temp1);
            });
        });
    }

    private void setMap(Map<Integer, RegionModel> tempMap, RegionModel start) {
        tempMap.put(start.getRegionCode(),start);
        if(start.getChildren() != null) {
            List<RegionModel> children = (List<RegionModel>) start.getChildren();
            for (RegionModel temp : children) {
                setMap(tempMap,temp);
            }
        }

    }

    /**
     *  根据regionCode 获取区域内实时预警
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @GetMapping(value = "/getAlertMsg")
    @ApiOperation(httpMethod = "GET", value = "根据regionCode 获取区域内实时预警", notes = "根据regionCode 获取区域内实时预警")
    public ResponseModel<List<AlertMsgDto>> getActualAlert(@RequestParam(name = "regionCodes", required = false) List<String> regionCodes) {
        return ResponseHelper.buildResponse(msgLogService.queryForAlertMsg(regionCodes));
    }
}

