package com.usky.iot.service.impl;

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.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.usky.common.core.bean.CommonPage;
import com.usky.common.core.exception.BusinessException;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.iot.domain.*;
import com.usky.iot.mapper.BaseBuildMapper;
import com.usky.iot.service.*;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.iot.service.vo.BaseBuildFacilityVO;
import com.usky.iot.service.vo.BuildFacilityRelateRequestVO;
import com.usky.iot.service.vo.BuildFacilityRelateResponeVO;
import com.usky.iot.service.vo.BuildFacilityStatusVO;
import org.apache.tomcat.jni.Local;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 建筑信息 服务实现类
 * </p>
 *
 * @author han
 * @since 2023-06-07
 */
@Service
public class BaseBuildServiceImpl extends AbstractCrudService<BaseBuildMapper, BaseBuild> implements BaseBuildService {

    @Autowired
    private BaseBuildFacilityRelateService baseBuildFacilityRelateService;

    @Autowired
    private BaseGgpFacilityService baseGgpFacilityService;

    @Autowired
    private BaseFacilityTypeService baseFacilityTypeService;

    @Autowired
    private BaseBuildFacilityService baseBuildFacilityService;

    @Autowired
    private BaseBuildFacilityTypeService baseBuildFacilityTypeService;

    @Autowired
    private DmpDeviceInfoService dmpDeviceInfoService;

    @Override
    public void add(BaseBuild baseBuild){
//        if(checkNameUnique(baseBuild)){
//            throw new BusinessException("新增建筑名称"+baseBuild.getBuildName()+"失败，该建筑名称已存在");
//        }
        baseBuild.setBuildNum("jz-"+new SimpleDateFormat("yyyyMMddHHmmssSSS").format(Calendar.getInstance().getTime()));
        baseBuild.setCreateBy(SecurityUtils.getUsername());
        baseBuild.setCreateTime(LocalDateTime.now());
        baseBuild.setTenantId(SecurityUtils.getTenantId());
        this.save(baseBuild);

    }

    @Override
    public void update(BaseBuild baseBuild){
//        if(checkNameUnique(baseBuild)){
//            throw new BusinessException("修改建筑名称"+baseBuild.getBuildName()+"失败，该建筑名称已存在");
//
//        }

        baseBuild.setUpdateBy(SecurityUtils.getUsername());
        baseBuild.setUpdateTime(LocalDateTime.now());
        this.updateById(baseBuild);
    }

    @Override
    public void remove(Integer id){
        BaseBuild baseBuild = this.getById(id);
        Optional.ofNullable(baseBuild).orElseThrow(() -> new BusinessException("该建筑不存在"));

        LambdaQueryWrapper<BaseBuildFacilityRelate> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(BaseBuildFacilityRelate::getBuildId,baseBuild.getBuildNum());
        Integer count = baseBuildFacilityRelateService.count(queryWrapper);
        if(count > 0){
            throw new BusinessException("该建筑下面有关联建筑设施，不能删除");
        }

        LambdaQueryWrapper<DmpDeviceInfo> queryWrapper1 = Wrappers.lambdaQuery();
        queryWrapper1.eq(DmpDeviceInfo::getBuildId,baseBuild.getBuildNum());
        Integer count1 = dmpDeviceInfoService.count(queryWrapper1);
        if(count1 > 0){
            throw new BusinessException("该建筑下面有关联设备，不能删除");
        }

        this.removeById(id);

    }

    @Override
    public List<BaseBuild> dataList(Integer id){
        LambdaQueryWrapper<BaseBuild> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(BaseBuild::getDeleteFlag,0)
                .eq(!ObjectUtils.isEmpty(id),BaseBuild::getId,id)
                .eq(BaseBuild::getTenantId,SecurityUtils.getTenantId())
                .orderByDesc(BaseBuild::getId);;
        List<BaseBuild> list = this.list(queryWrapper);
        if(CollectionUtils.isNotEmpty(list)){
            for(int i=0;i<list.size();i++){
                LambdaQueryWrapper<BaseBuildFacilityRelate> queryWrapper1 = Wrappers.lambdaQuery();
                queryWrapper1.eq(BaseBuildFacilityRelate::getBuildId,list.get(i).getId());
                Integer count = baseBuildFacilityRelateService.count(queryWrapper1);
                list.get(i).setBuildFacilityCount(count);
            }
        }

        return list;
    }

    @Override
    public CommonPage<BuildFacilityRelateResponeVO> buildFacilityRelateList(BuildFacilityRelateRequestVO requestVO){
        List<BuildFacilityRelateResponeVO> list = new ArrayList<>();

        LambdaQueryWrapper<BaseBuild> queryBuild = Wrappers.lambdaQuery();
        queryBuild.eq(BaseBuild::getId,requestVO.getBuildId())
                .eq(BaseBuild::getDeleteFlag,0)
                .eq(BaseBuild::getTenantId,SecurityUtils.getTenantId())
                .orderByDesc(BaseBuild::getId);
        BaseBuild buildOne = this.getOne(queryBuild);
        Integer buildFacilityId = buildOne.getFacilityId();

        IPage<BaseGgpFacility> page = new Page<>(requestVO.getCurrent(),requestVO.getSize());
        LambdaQueryWrapper<BaseGgpFacility> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(StringUtils.isNotBlank(requestVO.getFacilityNum()),BaseGgpFacility::getFacilityNum,requestVO.getFacilityNum())
                .eq(StringUtils.isNotBlank(requestVO.getFacilityType()),BaseGgpFacility::getFacilityType,requestVO.getFacilityType())
                .like(StringUtils.isNotBlank(requestVO.getFacilityName()),BaseGgpFacility::getFacilityName,
                        requestVO.getFacilityName())
                .eq(BaseGgpFacility::getTenantId,SecurityUtils.getTenantId());
        page = baseGgpFacilityService.page(page,queryWrapper);
        if(CollectionUtils.isNotEmpty(page.getRecords())){
            for(int i=0;i<page.getRecords().size();i++){
                BuildFacilityRelateResponeVO responeVO = new BuildFacilityRelateResponeVO();
                responeVO.setBuildId(requestVO.getBuildId());
                responeVO.setFacilityId(page.getRecords().get(i).getId());
                responeVO.setFacilityNum(page.getRecords().get(i).getFacilityNum());
                responeVO.setFacilityName(page.getRecords().get(i).getFacilityName());

                LambdaQueryWrapper<BaseFacilityType> queryWrapper1 = Wrappers.lambdaQuery();
                queryWrapper1.eq(BaseFacilityType::getTypeCode,page.getRecords().get(i).getFacilityType());
                BaseFacilityType one = baseFacilityTypeService.getOne(queryWrapper1);
                if(one != null){
                    responeVO.setFacilityType(one.getTypeName());
                }

                responeVO.setAddress(page.getRecords().get(i).getAddress());

                if(page.getRecords().get(i).getId().equals(buildFacilityId)){
                    responeVO.setStatus(1);
                    list.add(0, responeVO);
                }else{
                    responeVO.setStatus(0);
                    list.add(responeVO);
                }
            }
        }
        return new CommonPage<>(list,page.getTotal(),page.getSize(),page.getCurrent());
    }

    @Override
    public void setBuildFacilityStatus(BuildFacilityStatusVO statusVO){
        BaseBuild baseBuild = new BaseBuild();
        LambdaQueryWrapper<BaseBuild> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(BaseBuild::getDeleteFlag,0)
                .eq(BaseBuild::getId,statusVO.getBuildId())
                .eq(BaseBuild::getTenantId,SecurityUtils.getTenantId());
        BaseBuild one = this.getOne(queryWrapper);

        if(statusVO.getStatus() == 1){

            if(one.getFacilityId() != null && (""+one.getFacilityId()).length() > 1){
                throw new BusinessException("绑定失败，该建筑已绑定设施");
            }

            baseBuild.setId(statusVO.getBuildId());
            baseBuild.setFacilityId(statusVO.getFacilityId());
        }else{
            if(one == null){
                throw new BusinessException("该建筑信息不存在");
            }

            baseBuild.setId(statusVO.getBuildId());
            baseBuild.setFacilityId(0);
        }
        baseBuild.setUpdateBy(SecurityUtils.getUsername());
        baseBuild.setUpdateTime(LocalDateTime.now());
        this.updateById(baseBuild);



    }

    @Override
    public List<Object> buildFacilityInfo(BaseBuildFacilityVO baseBuildFacilityVO) {
        List<Object> list = new ArrayList<>();
        List<Object> list2 = new ArrayList<>();
        LambdaQueryWrapper<BaseBuildFacilityRelate> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(BaseBuildFacilityRelate::getBuildId,baseBuildFacilityVO.getId());
        List<BaseBuildFacilityRelate> baseBuildFacilityList = baseBuildFacilityRelateService.list(queryWrapper);
        BaseBuild baseBuild = this.getById(baseBuildFacilityVO.getId());
        Map<String, Object> map = new HashMap<>();
        map.put("aboveFloor", baseBuild.getAboveFloor());
        map.put("underFloor", baseBuild.getUnderFloor());
        if (CollectionUtils.isNotEmpty(baseBuildFacilityList)) {
            List<Integer> facilityIdList = new ArrayList<>();
            for (int i = 0; i < baseBuildFacilityList.size(); i++) {
                facilityIdList.add(baseBuildFacilityList.get(i).getFacilityId());
            }
            QueryWrapper<BaseBuildFacility> query2 = Wrappers.query();
            query2.select("floor as floor","count(id) as count","facility_type as facilityType")
                    .in("id",facilityIdList)
                    .in(CollectionUtils.isNotEmpty(baseBuildFacilityVO.getFacilityType()),"facility_type",
                            baseBuildFacilityVO.getFacilityType())
                    .eq("delete_flag",0)
                    .eq(StringUtils.isNotBlank(baseBuildFacilityVO.getFloor()),"floor",
                            baseBuildFacilityVO.getFloor())
                    .groupBy("floor","facility_type");
            List<Map<String, Object>> baseBuildFacilityList1 = baseBuildFacilityService.listMaps(query2);
            QueryWrapper<BaseBuildFacility> query3 = Wrappers.query();
            query3.select("floor as floor","count(id) as count")
                    .in("id",facilityIdList)
                    .in(CollectionUtils.isNotEmpty(baseBuildFacilityVO.getFacilityType()),"facility_type",
                            baseBuildFacilityVO.getFacilityType())
                    .eq("delete_flag",0)
                    .eq(StringUtils.isNotBlank(baseBuildFacilityVO.getFloor()),"floor",
                            baseBuildFacilityVO.getFloor())
                    .groupBy("floor")
                    .orderByAsc("floor+0");
            List<Map<String, Object>> baseBuildFacilityList2 = baseBuildFacilityService.listMaps(query3);
            QueryWrapper<BaseBuildFacility> query4 = Wrappers.query();
            query4.select("facility_type as facilityType","count(id) as count")
                    .in("id",facilityIdList)
                    .in(CollectionUtils.isNotEmpty(baseBuildFacilityVO.getFacilityType()),"facility_type",
                            baseBuildFacilityVO.getFacilityType())
                    .eq("delete_flag",0)
                    .eq(StringUtils.isNotBlank(baseBuildFacilityVO.getFloor()),"floor",
                            baseBuildFacilityVO.getFloor())
                    .groupBy("facility_type");
            List<Map<String, Object>> baseBuildFacilityList3 = baseBuildFacilityService.listMaps(query4);
            List<String> facilityTypeList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(baseBuildFacilityList3)) {
                for (int l = 0; l < baseBuildFacilityList3.size(); l++) {
                    facilityTypeList.add(baseBuildFacilityList3.get(l).get("facilityType").toString());
                }
            }
            LambdaQueryWrapper<BaseBuildFacilityType> queryWrapper1 = Wrappers.lambdaQuery();
            queryWrapper1.in(BaseBuildFacilityType::getTypeCode,facilityTypeList);
            List<BaseBuildFacilityType> baseBuildFacilityType = baseBuildFacilityTypeService.list(queryWrapper1);
            if (CollectionUtils.isNotEmpty(baseBuildFacilityList2)) {
                for (int j = 0; j < baseBuildFacilityList2.size(); j++){
                    Map<String, Object> map1 = new HashMap<>();
                    map1.put("floor", baseBuildFacilityList2.get(j).get("floor"));
                    List<Object> list1 = new ArrayList<>();
                    if (CollectionUtils.isNotEmpty(baseBuildFacilityList1)) {
                        for (int k = 0; k < baseBuildFacilityList1.size(); k++){
                            Map<String, Object> map2 = new HashMap<>();
                            if (baseBuildFacilityList2.get(j).get("floor").equals(baseBuildFacilityList1.get(k).get(
                                    "floor"))){
                                map2.put("facilityType", baseBuildFacilityList1.get(k).get("facilityType"));
                                map2.put("count", baseBuildFacilityList1.get(k).get("count"));
                                if (CollectionUtils.isNotEmpty(baseBuildFacilityType)) {
                                    for (int m = 0; m < baseBuildFacilityType.size(); m++) {
                                        if (baseBuildFacilityList1.get(k).get("facilityType").equals(baseBuildFacilityType.get(m).getTypeCode())){
                                            map2.put("typeImg", baseBuildFacilityType.get(m).getTypeImg());
                                            map2.put("typeName", baseBuildFacilityType.get(m).getTypeName());
                                        }
                                    }
                                }
                                list1.add(map2);
                            }
                        }
                    }
                    map1.put("facilityList", list1);
                    list.add(map1);
                }
            }
        }
        map.put("floorList", list);
        list2.add(map);
        return list2;
    }

    @Override
    public List<BaseBuildFacility> typeFacilityInfo(BaseBuildFacilityVO baseBuildFacilityVO) {
        LambdaQueryWrapper<BaseBuildFacilityRelate> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(BaseBuildFacilityRelate::getBuildId,baseBuildFacilityVO.getId());
        List<BaseBuildFacilityRelate> baseBuildFacilityList = baseBuildFacilityRelateService.list(queryWrapper);
        List<Integer> facilityIdList = new ArrayList<>();
        List<String> facilityCodeList = new ArrayList<>();
        List<BaseBuildFacility> list = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(baseBuildFacilityList)) {
            for (int i = 0; i < baseBuildFacilityList.size(); i++) {
                facilityIdList.add(baseBuildFacilityList.get(i).getFacilityId());
            }
            LambdaQueryWrapper<BaseBuildFacility> queryWrapper1 = Wrappers.lambdaQuery();
            queryWrapper1.in(BaseBuildFacility::getId,facilityIdList)
                    .in(CollectionUtils.isNotEmpty(baseBuildFacilityVO.getFacilityType()),BaseBuildFacility::getFacilityType,baseBuildFacilityVO.getFacilityType())
                    .eq(StringUtils.isNotBlank(baseBuildFacilityVO.getFloor()),BaseBuildFacility::getFloor,baseBuildFacilityVO.getFloor())
                    .eq(BaseBuildFacility::getDeleteFlag,0);
            list = baseBuildFacilityService.list(queryWrapper1);
            if (CollectionUtils.isNotEmpty(list)){
                for (int j = 0; j < list.size(); j++) {
                    if (!facilityCodeList.contains(list.get(j).getFacilityType())) {
                        facilityCodeList.add(list.get(j).getFacilityType());
                    }
                }
                LambdaQueryWrapper<BaseBuildFacilityType> queryWrapper2 = Wrappers.lambdaQuery();
                queryWrapper2.in(BaseBuildFacilityType::getTypeCode,facilityCodeList);
                List<BaseBuildFacilityType> typeList = baseBuildFacilityTypeService.list(queryWrapper2);
                if (CollectionUtils.isNotEmpty(typeList)){
                    for (int k = 0; k < list.size(); k++) {
                        for (int l = 0; l < typeList.size(); l++) {
                            if (list.get(k).getFacilityType().equals(typeList.get(l).getTypeCode())){
                                list.get(k).setModelLink(typeList.get(l).getModelLink());
                                list.get(k).setTypeName(typeList.get(l).getTypeName());
                            }
                        }
                    }
                }
            }
        }
        return list;
    }

    @Override
    public List<BaseBuildFacilityType> buildTypeInfo(Integer id) {
        LambdaQueryWrapper<BaseBuildFacilityRelate> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(BaseBuildFacilityRelate::getBuildId,id);
        List<BaseBuildFacilityRelate> baseBuildFacilityList = baseBuildFacilityRelateService.list(queryWrapper);
        List<Integer> facilityIdList = new ArrayList<>();
        List<BaseBuildFacilityType> baseBuildFacilityType = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(baseBuildFacilityList)) {
            for (int i = 0; i < baseBuildFacilityList.size(); i++) {
                facilityIdList.add(baseBuildFacilityList.get(i).getFacilityId());
            }
            QueryWrapper<BaseBuildFacility> query4 = Wrappers.query();
            query4.select("facility_type as facilityType","count(id) as count")
                    .in("id",facilityIdList)
                    .eq("delete_flag",0)
                    .groupBy("facility_type");
            List<Map<String, Object>> baseBuildFacilityList5 = baseBuildFacilityService.listMaps(query4);
            List<String> facilityTypeList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(baseBuildFacilityList5)) {
                for (int l = 0; l < baseBuildFacilityList5.size(); l++) {
                    facilityTypeList.add(baseBuildFacilityList5.get(l).get("facilityType").toString());
                }
            }
            LambdaQueryWrapper<BaseBuildFacilityType> queryWrapper1 = Wrappers.lambdaQuery();
            queryWrapper1.in(BaseBuildFacilityType::getTypeCode,facilityTypeList);
            baseBuildFacilityType = baseBuildFacilityTypeService.list(queryWrapper1);
        }
        return baseBuildFacilityType;
    }

//    @Override
//    public boolean checkNameUnique(BaseBuild baseBuild){
//        Integer id = null == baseBuild.getId()?-1:baseBuild.getId();
//        LambdaQueryWrapper<BaseBuild> queryWrapper = Wrappers.lambdaQuery();
//        queryWrapper.eq(BaseBuild::getBuildName,baseBuild.getBuildName())
//                .eq(BaseBuild::getDeleteFlag,0)
//                .eq(BaseBuild::getTenantId,SecurityUtils.getTenantId());
//        BaseBuild one = this.getOne(queryWrapper);
//        return null != one && !Objects.equals(one.getId(),id);
//    }
}




