package com.usky.iot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
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.BaseBuildFacilityMapper;
import com.usky.iot.mapper.BaseBuildFacilityTypeMapper;
import com.usky.iot.mapper.DmpProductAttributeMapper;
import com.usky.iot.service.*;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.iot.service.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 建筑设施 服务实现类
 * </p>
 *
 * @author han
 * @since 2023-07-26
 */
@Service
public class BaseBuildFacilityServiceImpl extends AbstractCrudService<BaseBuildFacilityMapper, BaseBuildFacility> implements BaseBuildFacilityService {
    @Autowired
    private BaseBuildFacilityRelateService baseBuildFacilityRelateService;
//
//    @Autowired
//    private BaseBuildService baseBuildService;

    @Autowired
    private DmpDeviceInfoService dmpDeviceInfoService;

    @Autowired
    private DmpDeviceTypeService dmpDeviceTypeService;

    @Autowired
    private BaseBuildFacilityMapper baseBuildFacilityMapper;

    @Autowired
    private BaseBuildFacilityTypeMapper baseBuildFacilityTypeMapper;

    @Autowired
    private DmpProductAttributeMapper dmpProductAttributeMapper;

    @Override
    public void add(BaseBuildFacility baseBuildFacility){
        baseBuildFacility.setFacilityNum("jzss-"+new SimpleDateFormat("yyyyMMddHHmmssSSS").format(Calendar.getInstance().getTime()));
        baseBuildFacility.setTenantId(SecurityUtils.getTenantId());
        baseBuildFacility.setCreateBy(SecurityUtils.getUsername());
        baseBuildFacility.setCreateTime(LocalDateTime.now());
        this.save(baseBuildFacility);

        Integer id = baseBuildFacility.getId();
        BaseBuildFacilityRelate relate = new BaseBuildFacilityRelate();
        relate.setBuildId(baseBuildFacility.getBuildId());
        relate.setFacilityId(id);
        relate.setCreateBy(SecurityUtils.getUsername());
        relate.setCreateTime(LocalDateTime.now());
        baseBuildFacilityRelateService.save(relate);
    }

    @Override
    public void update(BaseBuildFacility baseBuildFacility){
        baseBuildFacility.setUpdateBy(SecurityUtils.getUsername());
        baseBuildFacility.setUpdateTime(LocalDateTime.now());
        this.updateById(baseBuildFacility);
    }

    @Override
    public void remove(Integer id){
        BaseBuildFacility one = this.getById(id);
        Optional.ofNullable(one).orElseThrow(() -> new BusinessException("无记录"));

        LambdaQueryWrapper<BaseBuildFacilityRelate> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(BaseBuildFacilityRelate::getFacilityId,id);
        BaseBuildFacilityRelate one1 = baseBuildFacilityRelateService.getOne(queryWrapper);
        if(one1 != null){
            baseBuildFacilityRelateService.removeById(one1.getId());
        }

        one.setDeleteFlag(1);
        this.updateById(one);
    }

    @Override
    public CommonPage<BaseBuildFacility> page(BaseBuildFacilityRequestVO requestVO){
        List<BaseBuildFacility> list = new ArrayList<>();
        LambdaQueryWrapper<BaseBuildFacility> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(requestVO.getId() != null,BaseBuildFacility::getId,requestVO.getId())
                .like(StringUtils.isNotBlank(requestVO.getFacilityNum()),BaseBuildFacility::getFacilityNum,requestVO.getFacilityNum())
                .like(StringUtils.isNotBlank(requestVO.getFacilityName()),BaseBuildFacility::getFacilityName,requestVO.getFacilityName())
                .eq(StringUtils.isNotBlank(requestVO.getFacilityType()),BaseBuildFacility::getFacilityType,requestVO.getFacilityType())
                .eq(BaseBuildFacility::getDeleteFlag,0)
                .eq(BaseBuildFacility::getTenantId,SecurityUtils.getTenantId())
                .orderByDesc(BaseBuildFacility::getId);
        List<BaseBuildFacility> list1 = this.list(queryWrapper);
        if(CollectionUtils.isNotEmpty(list1)){
            List<BaseBuildFacilityRelate> facilityList = new ArrayList<>();
            List<BaseBuild> baseBuildList = new ArrayList<>();

            List<Integer> facilityId = list1.stream().map(s ->s.getId()).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(facilityId)){
                LambdaQueryWrapper<BaseBuildFacilityRelate> queryWrapper1 = Wrappers.lambdaQuery();
                queryWrapper1.in(BaseBuildFacilityRelate::getFacilityId,facilityId);
                facilityList = baseBuildFacilityRelateService.list(queryWrapper1);
                if(CollectionUtils.isNotEmpty(facilityList)){
                    List<Integer> buildIdList = facilityList.stream().map(s ->s.getBuildId()).collect(Collectors.toList());
                    baseBuildList = baseMapper.getBuildName(buildIdList);
                }
            }

            for(int i=0;i<list1.size();i++){
                for(int j=0;j<facilityList.size();j++){
                    if(list1.get(i).getId().equals(facilityList.get(j).getFacilityId())){
                        for(int k=0;k<baseBuildList.size();k++){
                            if(facilityList.get(j).getBuildId().equals(baseBuildList.get(k).getId())){
                                list1.get(i).setBuildId(baseBuildList.get(k).getId());
                                list1.get(i).setBuildName(baseBuildList.get(k).getBuildName());
                            }
                        }
                    }
                }

                BaseBuildFacilityType typeOne = baseMapper.baseBuildFacilityTypeList(list1.get(i).getFacilityType());
                list1.get(i).setTypeName(typeOne.getTypeName());
            }
        }


        if(StringUtils.isNotBlank(requestVO.getBuildName())){
            list1 = list1.stream().filter(m-> m.getBuildName().contains(requestVO.getBuildName())).collect(Collectors.toList());
        }

        if(requestVO.getBuildId() != null){
            list1 = list1.stream().filter(m-> m.getBuildId().equals(requestVO.getBuildId())).collect(Collectors.toList());
        }

        if(list1.size() > 0){
            for(int j=0;j<list1.size();j++){
                list.add(list1.get(j));
            }
        }

        Integer total = 0;
        if(list.size() > 0){
            total = list.size();
        }

        Integer pageCurrent = requestVO.getCurrent();
        Integer pageSize = requestVO.getSize();
        Integer current = 0;
        if(pageCurrent!=null && pageSize>0){
            current = (pageCurrent-1)*pageSize;
        }
        List<BaseBuildFacility> records = list.stream().skip(current).limit(pageSize).collect(Collectors.toList());

        return new CommonPage<>(records,total,pageSize,pageCurrent);
    }

    @Override
    public CommonPage<BuildFacilityResponeVO> deviceList(BuildFacilityRequestVO requestVO){
        List<BuildFacilityResponeVO> list = new ArrayList<>();

        LambdaQueryWrapper<BaseBuildFacility> query = Wrappers.lambdaQuery();
        query.eq(BaseBuildFacility::getId,requestVO.getBaseBuildFacilityId())
                .eq(BaseBuildFacility::getTenantId,SecurityUtils.getTenantId())
                .eq(BaseBuildFacility::getDeleteFlag,0);
        BaseBuildFacility buildFacilityOne = this.getOne(query);
        String relateDeviceId = buildFacilityOne.getDeviceId();

        IPage<DmpDeviceInfo> page = new Page<>(requestVO.getCurrent(),requestVO.getSize());
        LambdaQueryWrapper<DmpDeviceInfo> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(StringUtils.isNotBlank(requestVO.getDeviceId()),DmpDeviceInfo::getDeviceId,requestVO.getDeviceId())
                .eq(requestVO.getDeviceType() != null,DmpDeviceInfo::getDeviceType,requestVO.getDeviceType())
                .eq(DmpDeviceInfo::getTenantId,SecurityUtils.getTenantId())
                .eq(DmpDeviceInfo::getDeleteFlag,0);
        page = dmpDeviceInfoService.page(page,queryWrapper);
        if(CollectionUtils.isNotEmpty(page.getRecords())){
            for(int i=0;i<page.getRecords().size();i++){
                BuildFacilityResponeVO responeVO = new BuildFacilityResponeVO();
                responeVO.setBaseBuildFacilityId(requestVO.getBaseBuildFacilityId());

                responeVO.setDeviceId(page.getRecords().get(i).getDeviceId());
                responeVO.setDeviceName(page.getRecords().get(i).getDeviceName());

                LambdaQueryWrapper<DmpDeviceType> queryWrapper1 = Wrappers.lambdaQuery();
                queryWrapper1.eq(DmpDeviceType::getTypeCode,page.getRecords().get(i).getDeviceType().toString());
                DmpDeviceType one = dmpDeviceTypeService.getOne(queryWrapper1);
                if(one != null){
                    responeVO.setDeviceTypeName(one.getTypeName());
                }

                responeVO.setInstallAddress(page.getRecords().get(i).getInstallAddress());

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

    @Override
    public List<FacilityDeviceResultVO> facilityDeviceInfo(FacilityDeviceQueryVO queryVO){
        List<FacilityDeviceResultVO> list = new ArrayList<>();
        List<String> facilityList = queryVO.getFacilityNum();
        if(facilityList.size() > 0){
            List<String> facilityTypeList = new ArrayList<>();
            List<String> deviceIdList = new ArrayList<>();
            List<Integer> productIdList = new ArrayList<>();
            List<ProductAttributeListVO> productAttributeList = new ArrayList<>();
            LambdaQueryWrapper<BaseBuildFacility> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.in(BaseBuildFacility::getFacilityNum,facilityList)
                    .eq(BaseBuildFacility::getDeleteFlag,0)
                    .eq(BaseBuildFacility::getTenantId,SecurityUtils.getTenantId());
            Integer tenantId = SecurityUtils.getTenantId();
            List<BaseBuildFacility> list1 = this.list(queryWrapper);
            if(CollectionUtils.isNotEmpty(list1)){
                for (int i = 0; i < list1.size(); i++) {
                    if(facilityTypeList.contains(list1.get(i).getFacilityType())){

                    }else{
                        facilityTypeList.add(list1.get(i).getFacilityType());
                    }
                    deviceIdList.add(list1.get(i).getDeviceId());
                }
            }
            List<BaseBuildFacilityType> baseBuildFacilityTypeList = new ArrayList<>();
            if(facilityTypeList.size() > 0){
                LambdaQueryWrapper<BaseBuildFacilityType> queryWrapper1 = Wrappers.lambdaQuery();
                queryWrapper1.in(BaseBuildFacilityType::getTypeCode,facilityTypeList)
                        .eq(BaseBuildFacilityType::getTenantId,SecurityUtils.getTenantId());
                baseBuildFacilityTypeList = baseBuildFacilityTypeMapper.selectList(queryWrapper1);
            }
            List<DmpDeviceInfo> deviceInfoList = new ArrayList<>();

            if(deviceIdList.size() > 0){
                LambdaQueryWrapper<DmpDeviceInfo> queryWrapper1 = Wrappers.lambdaQuery();
                queryWrapper1.in(DmpDeviceInfo::getDeviceId,deviceIdList)
                        .eq(DmpDeviceInfo::getDeleteFlag,0)
                        .eq(DmpDeviceInfo::getTenantId,SecurityUtils.getTenantId());
                deviceInfoList = dmpDeviceInfoService.list(queryWrapper1);
                if(CollectionUtils.isNotEmpty(deviceInfoList)){
                    for (int i = 0; i < deviceInfoList.size(); i++) {
                        if(productIdList.contains(deviceInfoList.get(i).getProductId())){

                        }else{
                            productIdList.add(deviceInfoList.get(i).getProductId());
                        }
                    }
                    if(productIdList.size() > 0){
                        List<ProductAttributeVO> attributeList = new ArrayList<>();
                        LambdaQueryWrapper<DmpProductAttribute> queryWrapper2 = Wrappers.lambdaQuery();
                        queryWrapper2.in(DmpProductAttribute::getProductId,productIdList)
                                .eq(DmpProductAttribute::getDeleteFlag,0)
                                .eq(DmpProductAttribute::getTenantId,SecurityUtils.getTenantId());
                        List<DmpProductAttribute> list2 = dmpProductAttributeMapper.selectList(queryWrapper2);

                        if(CollectionUtils.isNotEmpty(list2)){
                            for (int i = 0; i < deviceInfoList.size(); i++) {
                                ProductAttributeListVO productAttributeListVO = new ProductAttributeListVO();
                                productAttributeListVO.setDeviceId(deviceInfoList.get(i).getDeviceId());
                                for (int j = 0; j < list2.size(); j++) {
                                    if(deviceInfoList.get(i).getProductId().equals(list2.get(j).getProductId())){
                                        ProductAttributeVO productAttributeVO = new ProductAttributeVO();
                                        productAttributeVO.setAttributeName(list2.get(j).getAttributeName());
                                        productAttributeVO.setAttributeCode(list2.get(j).getAttributeCode());
                                        productAttributeVO.setAttributeType(list2.get(j).getAttributeType());
                                        productAttributeVO.setDataType(list2.get(j).getDataType());
                                        productAttributeVO.setAttributeLength(list2.get(j).getAttributeLength());
                                        productAttributeVO.setAttributeUnit(list2.get(j).getAttributeUnit());
                                        attributeList.add(productAttributeVO);

                                    }
                                }
                                productAttributeListVO.setAttributeList(attributeList);
                                productAttributeList.add(productAttributeListVO);
                            }

                        }

                    }
                }
            }

            LambdaQueryWrapper<BaseBuildFacility> queryWrapper1 = Wrappers.lambdaQuery();
            queryWrapper1.in(BaseBuildFacility::getFacilityNum,facilityList)
                    .eq(BaseBuildFacility::getDeleteFlag,0)
                    .eq(BaseBuildFacility::getTenantId,SecurityUtils.getTenantId());
            List<BaseBuildFacility> list2 = baseBuildFacilityMapper.selectList(queryWrapper);
            if(CollectionUtils.isNotEmpty(list2)){
                for (int i = 0; i < list2.size(); i++) {
                    FacilityDeviceResultVO resultVO = new FacilityDeviceResultVO();
                    resultVO.setFacilityNum(list2.get(i).getFacilityNum());
                    resultVO.setFacilityName(list2.get(i).getFacilityName());
                    resultVO.setFacilityType(list2.get(i).getFacilityType());
                    resultVO.setFacilityAddress(list2.get(i).getAddress());
                    if(CollectionUtils.isNotEmpty(baseBuildFacilityTypeList)){
                        for (int j = 0; j < baseBuildFacilityTypeList.size(); j++) {
                            if(list2.get(i).getFacilityType().equals(baseBuildFacilityTypeList.get(j).getTypeCode())){
                                resultVO.setTypeImg(baseBuildFacilityTypeList.get(j).getTypeImg());
                            }

                        }
                    }

                    if(CollectionUtils.isNotEmpty(deviceInfoList)){
                        for (int j = 0; j < deviceInfoList.size(); j++) {
                            if(list2.get(i).getDeviceId().equals(deviceInfoList.get(j).getDeviceId())){
                                resultVO.setDeviceName(deviceInfoList.get(j).getDeviceName());
                                resultVO.setDeviceAddress(deviceInfoList.get(j).getInstallAddress());
                                resultVO.setDeviceId(deviceInfoList.get(j).getDeviceId());
                                resultVO.setProductCode(deviceInfoList.get(j).getProductCode());
                            }
                        }
                    }
                    if(CollectionUtils.isNotEmpty(productAttributeList)){
                        for (int j = 0; j < productAttributeList.size(); j++) {
                            if(list2.get(i).getDeviceId().equals(productAttributeList.get(j).getDeviceId())){
                                resultVO.setDataField(productAttributeList.get(j).getAttributeList());
                            }
                        }
                    }
                    list.add(resultVO);
                }
            }
        }
        return list;
    }

    @Override
    public void setStatus(FacilityDeviceStatusVO statusVO){
        BaseBuildFacility baseBuildFacility = new BaseBuildFacility();

        LambdaQueryWrapper<BaseBuildFacility> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(BaseBuildFacility::getDeleteFlag,0)
                .eq(BaseBuildFacility::getTenantId,SecurityUtils.getTenantId())
                .eq(BaseBuildFacility::getId,statusVO.getBaseBuildFacilityId());
        BaseBuildFacility one = this.getOne(queryWrapper);
        if(statusVO.getStatus() == 1){
            if(one.getDeviceId() != null && (""+one.getDeviceId()).length() > 1){
                throw new BusinessException("绑定失败，该建筑设施已绑定设备");
            }
            baseBuildFacility.setId(one.getId());
            baseBuildFacility.setDeviceId(statusVO.getDeviceId());
        }else{
            if(one == null){
                throw new BusinessException("无记录");
            }
            baseBuildFacility.setId(one.getId());
            baseBuildFacility.setDeviceId("0");
        }
        baseBuildFacility.setUpdateBy(SecurityUtils.getUsername());
        baseBuildFacility.setUpdateTime(LocalDateTime.now());
        this.updateById(baseBuildFacility);

    }

}





