package com.yuchen.saas.park.service.service.pldoor.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.thinkunion.sdk.iot.bean.api.CallingDeviceServiceResponse;
import com.yuchen.saas.device.api.dto.deviceCenter.SyncDeviceDataDeleteReqDTO;
import com.yuchen.saas.device.api.dto.deviceCenter.SyncDeviceDataSubmitReqDTO;
import com.yuchen.saas.device.api.entity.deviceCenter.SaasDeviceSmartHardware;
import com.yuchen.saas.device.api.feign.deviceCenter.DeviceCenterFeign;
import com.yuchen.saas.park.api.dto.pldoor.CallDeviceServiceDto;
import com.yuchen.saas.park.api.entity.park.PmgBatParkInfo;
import com.yuchen.saas.park.api.entity.pldoor.PlDoorPoint;
import com.yuchen.saas.park.api.entity.pldoor.PlDoorPointGroup;
import com.yuchen.saas.park.api.entity.pldoor.PlDoorPointGroupItem;
import com.yuchen.saas.park.api.entity.property.PropertyBuildingUnit;
import com.yuchen.saas.park.api.entity.property.PropertyBuildings;
import com.yuchen.saas.park.api.vo.door.PlDoorPointForRobotVO;
import com.yuchen.saas.park.api.vo.door.PlDoorPointVO;
import com.yuchen.saas.park.api.vo.pldoor.*;
import com.yuchen.saas.park.api.vo.request.PlDoorPointReq;
import com.yuchen.saas.park.service.iot.IoTRemoteService;
import com.yuchen.saas.park.service.mapper.pldoor.PlDoorPointMapper;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import com.yuchen.saas.park.service.service.pldoor.PlDoorPointGroupItemService;
import com.yuchen.saas.park.service.service.pldoor.PlDoorPointGroupService;
import com.yuchen.saas.park.service.service.pldoor.PlDoorPointService;
import com.yuchen.saas.park.service.service.property.PropertyBuildingUnitService;
import com.yuchen.saas.park.service.service.property.PropertyBuildingsLevelService;
import com.yuchen.saas.park.service.service.property.PropertyBuildingsService;
import com.yuchen.saas.park.service.service.property.PropertyHousesService;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.mp.support.Query;
import org.nest.springwrap.core.secure.utils.AuthUtil;
import org.nest.springwrap.core.tool.utils.BeanUtil;
import org.nest.springwrap.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 门禁点 服务实现类
 * </p>
 *
 * @author miaoqs
 * @since 2024-04-03
 */
@Slf4j
@Service
public class PlDoorPointServiceImpl extends BaseServiceImpl<PlDoorPointMapper, PlDoorPoint> implements PlDoorPointService {

    @Lazy
    @Autowired
    private PlDoorPointGroupService plDoorPointGroupService;
    @Autowired
    private PlDoorPointGroupItemService plDoorPointGroupItemService;
    @Resource
    private DeviceCenterFeign deviceCenterFeign;
    @Resource
    private PlDoorPointMapper plDoorPointMapper;
    @Resource
    private PmgBatParkInfoService pmgBatParkInfoService;
    @Resource
    private PropertyBuildingsService propertyBuildingsService;
    @Resource
    private PropertyBuildingUnitService propertyBuildingUnitService;
    @Resource
    private PropertyBuildingsLevelService propertyBuildingsLevelService;
    @Resource
    private PropertyHousesService propertyHousesService;
    @Resource
    private IoTRemoteService ioTRemoteService;

    private final String PAGELIST = "pageList";
    //麦驰门禁设备产品KEY
    private final String ProducktKey = "ARZueO1QNfnv5lEe";

    //private final String DeviceName = "FBkYjrJdzLBvJ0c0";

    //大类（1：视频监控，2：智能硬件，3：传感设备）
    private final String broadCategory = "2";

    @Override
    @Transactional
    public boolean saveOrUpdateByParam(PlDoorPoint plDoorPoint) {
        //校验设备编号是否已存在
        if (plDoorPoint.getId() == null && new LambdaQueryChainWrapper<>(this.baseMapper).eq(PlDoorPoint::getDeviceNo, plDoorPoint.getDeviceNo()).count() > 0) {
            throw new RuntimeException("设备编号已存在");
        }
        if(Func.isNotEmpty(plDoorPoint.getId()) && new LambdaQueryChainWrapper<>(this.baseMapper).
                eq(PlDoorPoint::getDeviceNo, plDoorPoint.getDeviceNo())
                .ne(PlDoorPoint::getId, plDoorPoint.getId()).count() > 0){
            throw new RuntimeException("设备编号已存在");
        }
        if (Func.isNotEmpty(plDoorPoint.getId())) {
            //修改时删除原有门禁组子表
            PlDoorPoint point = getById(plDoorPoint.getId());
            if(Func.isNotEmpty(point.getDoorGroupId()) && Func.isNotEmpty(plDoorPoint.getDoorGroupId())){
                plDoorPointGroupItemService.remove(new LambdaQueryWrapper<PlDoorPointGroupItem>()
                        .eq(PlDoorPointGroupItem::getPlDoorPointId, point.getId())
                        .eq(PlDoorPointGroupItem::getPlDoorPointGroupId, point.getDoorGroupId()));
            }
        }

        //新增或保存门禁点
        this.saveOrUpdate(plDoorPoint);
        //同步智能硬件
        syncDeviceData(plDoorPoint);
        //保存门禁组子表
        PlDoorPointGroupItem item = plDoorPointGroupItemService.getOne(new LambdaQueryWrapper<PlDoorPointGroupItem>()
                .eq(PlDoorPointGroupItem::getPlDoorPointGroupId, plDoorPoint.getDoorGroupId())
                .eq(PlDoorPointGroupItem::getPlDoorPointId, plDoorPoint.getId())
                .last("limit 1"));
        if(Func.isNotEmpty(item)){
            return true;
        }
        PlDoorPointGroupItem plDoorPointGroupItem = new PlDoorPointGroupItem();
        plDoorPointGroupItem.setPlDoorPointGroupId(plDoorPoint.getDoorGroupId());
        plDoorPointGroupItem.setPlDoorPointId(plDoorPoint.getId());
        return plDoorPointGroupItemService.save(plDoorPointGroupItem);
    }

    @Override
    public void removeByIdParam(PlDoorPoint plDoorPoint) {
        PlDoorPoint point = this.getById(plDoorPoint.getId());
        this.removeById(plDoorPoint.getId());
        syncDeleteDeviceData(point);
    }

    /**
     * 同步设备到智能硬件中心
     */
    private void syncDeviceData(PlDoorPoint plDoorPoint){
        SyncDeviceDataSubmitReqDTO syncDeviceDataSubmitReqDTO = new SyncDeviceDataSubmitReqDTO();
        syncDeviceDataSubmitReqDTO.setBroadCategory(broadCategory);
        SaasDeviceSmartHardware saasDeviceSmartHardware = new SaasDeviceSmartHardware();
        saasDeviceSmartHardware.setCustomerId(AuthUtil.getUser().getCustomerManageId());
        saasDeviceSmartHardware.setProjectId(plDoorPoint.getParkId());
        //saasDeviceSmartHardware.setSpaceId();
        saasDeviceSmartHardware.setSmartHardwareType(plDoorPoint.getDeviceType());
        saasDeviceSmartHardware.setProductKey(plDoorPoint.getProductKey());
        saasDeviceSmartHardware.setDeviceName(plDoorPoint.getDeviceName());
        saasDeviceSmartHardware.setDeviceImages(plDoorPoint.getImgUrl());
        saasDeviceSmartHardware.setDeviceState(plDoorPoint.getEnableState());
        saasDeviceSmartHardware.setDeviceAlias(plDoorPoint.getDeviceName());
        saasDeviceSmartHardware.setDeviceAddress(plDoorPoint.getDeviceLocation());
        //saasDeviceSmartHardware.setLastConnectionTime();
        //saasDeviceSmartHardware.setLastBreakTime();
        //saasDeviceSmartHardware.setRemark();
        syncDeviceDataSubmitReqDTO.setSaasDeviceSmartHardware(saasDeviceSmartHardware);
        deviceCenterFeign.syncSubmitDeviceData(syncDeviceDataSubmitReqDTO);
    }

    /**
     * 同步删除设备到智能硬件中心
     */
    private void syncDeleteDeviceData(PlDoorPoint plDoorPoint){
        SyncDeviceDataDeleteReqDTO reqDTO = new SyncDeviceDataDeleteReqDTO();
        reqDTO.setBroadCategory(broadCategory);
        reqDTO.setDeviceName(plDoorPoint.getDeviceNo());
        deviceCenterFeign.syncDeleteDeviceData(reqDTO);
    }

    @Override
    public IPage<PlDoorPointVO> pageByparam(Page<PlDoorPointReq> page, @Param("req") PlDoorPointReq req) {
        Page<PlDoorPointVO> plDoorPointVOPage = plDoorPointMapper.listByParam(page, req);

        if (Func.isNotEmpty(plDoorPointVOPage) && Func.isNotEmpty(plDoorPointVOPage.getRecords())){
            List<PlDoorPointVO> pointList = plDoorPointVOPage.getRecords();
            for (PlDoorPointVO plDoorPointForRobotVO : pointList) {
                String groupStr = "";
                List<PlDoorPointGroupItem> list = plDoorPointGroupItemService.list(
                        new LambdaQueryWrapper<PlDoorPointGroupItem>().eq(PlDoorPointGroupItem::getPlDoorPointId, plDoorPointForRobotVO.getId()));
                if(Func.isNotEmpty(list)){
                    for (PlDoorPointGroupItem pointGroupItem : list) {
                        PlDoorPointGroup pointGroup = plDoorPointGroupService.getById(pointGroupItem.getPlDoorPointGroupId());
                        if(Func.isNotEmpty(pointGroup)){
                            groupStr += pointGroup.getPointGroupName()+",";
                        }
                    }
                }
                plDoorPointForRobotVO.setDoorGroupStr(groupStr);
                //空间名称
                PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(plDoorPointForRobotVO.getParkId());
                plDoorPointForRobotVO.setParkName(null == parkInfo?"":parkInfo.getParkName());
                PropertyBuildings buildings = propertyBuildingsService.getById(plDoorPointForRobotVO.getBuildingId());
                plDoorPointForRobotVO.setBuildingName(null == buildings?"":buildings.getBuildingName());
                PropertyBuildingUnit unit = propertyBuildingUnitService.getById(plDoorPointForRobotVO.getElementId());
                plDoorPointForRobotVO.setElementName(null == unit?"":unit.getUnitName());
            }
        }
        return plDoorPointVOPage;

    }

    @Override
    public List<PlDoorPoint> listByparam(PlDoorPointReq plDoorPointReq) {
        if(Func.isNotEmpty(plDoorPointReq) && Func.isNotEmpty(plDoorPointReq.getDoorName())){
            return this.list(new LambdaQueryWrapper<PlDoorPoint>().eq(PlDoorPoint::getDoorName, plDoorPointReq.getDoorName()));
        }
        return this.list();
    }

    @Override
    public PlDoorPointVO getDetailById(Long id) {
        PlDoorPoint point = this.getById(id);
        PlDoorPointVO plDoorPointVO = BeanUtil.copy(point, PlDoorPointVO.class);
        String faceState = point.getFaceState();
        String fingerprintState = point.getFingerprintState();
        String bluetoothState = point.getBluetoothState();
        String qrcodeState = point.getQrcodeState();
        int sum = Integer.valueOf(faceState)+Integer.valueOf(fingerprintState)+Integer.valueOf(bluetoothState)+Integer.valueOf(qrcodeState);
        String[] biologys = new String[sum];
        int index = 0; // 用于跟踪数组中下一个空闲位置
        if (faceState.equals("1")) {
            biologys[index++] = "1";
        }
        if (fingerprintState.equals("1")) {
            biologys[index++] = "2";
        }
        if (bluetoothState.equals("1")) {
            biologys[index++] = "3";
        }
        if (qrcodeState.equals("1")) {
            biologys[index++] = "3";
        }
        plDoorPointVO.setBiologys(biologys);
        return plDoorPointVO;
    }

    @Override
    public List<PlDoorPointForRobotVO> getPointListForRobot(Long parkId) {
        List<PlDoorPoint> list = this.list(new LambdaQueryWrapper<PlDoorPoint>().eq(PlDoorPoint::getParkId, parkId));
        List<PlDoorPointForRobotVO> plDoorPointForRobotVOList = new ArrayList<>();
        if(Func.isNotEmpty(list)){
            for (PlDoorPoint plDoorPoint : list) {
                PlDoorPointForRobotVO plDoorPointForRobotVO = new PlDoorPointForRobotVO();
                BeanUtil.copy(plDoorPoint, plDoorPointForRobotVO);
                //空间名称
                PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(plDoorPointForRobotVO.getParkId());
                plDoorPointForRobotVO.setParkName(null == parkInfo?"":parkInfo.getParkName());
                PropertyBuildings buildings = propertyBuildingsService.getById(plDoorPointForRobotVO.getBuildingId());
                plDoorPointForRobotVO.setBuildingName(null == buildings?"":buildings.getBuildingName());
                PropertyBuildingUnit unit = propertyBuildingUnitService.getById(plDoorPointForRobotVO.getElementId());
                plDoorPointForRobotVO.setElementName(null == unit?"":unit.getUnitName());
                plDoorPointForRobotVOList.add(plDoorPointForRobotVO);
            }
        }
        return plDoorPointForRobotVOList;
    }


    @Override
    public List<IotDeviceInfoVO> getIotPageList(Query query){
        CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
        callDeviceServiceDto.setIdentify(PAGELIST);
        callDeviceServiceDto.setProductKey(ProducktKey);
        //callDeviceServiceDto.setDeviceName(DeviceName);
        Map<String, Object> in = new HashMap<>();
        in.put("pageNum", query.getCurrent());
        in.put("pageSize", query.getSize());
        callDeviceServiceDto.setParams(in);
        String json = JSONObject.toJSONString(callDeviceServiceDto);
        Map map = JSONObject.parseObject(json, Map.class);
        CallingDeviceServiceResponse response = ioTRemoteService.callServiceReturn(map);
        if(Func.isNotEmpty(response)){
            String resultJson = JSONObject.toJSONString(response);
            log.info("====== IOT返回数据：{}",resultJson);
            List<IotDeviceInfoVO> iotDeviceInfoVOList = new ArrayList<>();
            IotResponseVO iotResponseVO = JSONObject.parseObject(resultJson, IotResponseVO.class);
            String dataStr = iotResponseVO.getData();
            IotResponseDataVO dataVO = JSONObject.parseObject(dataStr, IotResponseDataVO.class);
            String data2Str = dataVO.getData();
            IotResponseDataInfoVO iotResponseDataInfoVO = JSONObject.parseObject(data2Str, IotResponseDataInfoVO.class);
            String datasStr = iotResponseDataInfoVO.getDatas();
            IotDeviceInfoPageVO iotDeviceInfoPageVO = JSONObject.parseObject(datasStr, IotDeviceInfoPageVO.class);
            String rowsStr = iotDeviceInfoPageVO.getRows();
            JSONArray jsonArray = JSONArray.parseArray(rowsStr);
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject1 = jsonArray.getJSONObject(i);
                IotDeviceInfoVO iotDeviceInfoVO = JSONObject.parseObject(jsonObject1.toString(), IotDeviceInfoVO.class);
                System.out.println(iotDeviceInfoVO.getTerminalNumber());
                iotDeviceInfoVOList.add(iotDeviceInfoVO);
            }
            return iotDeviceInfoVOList;
        }
        return null;
    }

    /* public static void main(String[] args) {
        String jsonStr = "{\"Code\":\"200\",\"Data\":{\"Message\":\"\",\"Data\":{\"Msg\":\"操作成功\",\"Datas\":\"{\\\"totalPage\\\":1,\\\"pageNo\\\":1,\\\"pageSize\\\":20,\\\"totalRows\\\":3,\\\"rows\\\":[{\\\"terminalNumber\\\":\\\"M00010101000\\\",\\\"progName\\\":\\\"STBD9\\\",\\\"idCard\\\":\\\"\\\",\\\"remark\\\":\\\"\\\",\\\"isOnline\\\":1,\\\"tenementName\\\":\\\"\\\",\\\"firmwareUpdate\\\":\\\"\\\",\\\"magneticDoorStatus\\\":1,\\\"serverIpAddress\\\":\\\"192.168.1.222\\\",\\\"cellphone\\\":\\\"\\\",\\\"id\\\":2638,\\\"email\\\":\\\"\\\",\\\"terminalDesc\\\":\\\"0001栋01单元01号门口机\\\",\\\"ipAddress\\\":\\\"192.168.1.204\\\",\\\"updateUser\\\":1,\\\"telephone\\\":\\\"\\\",\\\"updateTime\\\":1728499091000,\\\"progVersion\\\":\\\"McB10IM01-5002B8\\\",\\\"subnetMask\\\":\\\"255.255.255.0\\\",\\\"terminalType\\\":\\\"M\\\",\\\"macAddress\\\":\\\"0050C6017BF3\\\",\\\"deleted\\\":false,\\\"createTime\\\":1711611851000,\\\"createUser\\\":1,\\\"gatewayAddress\\\":\\\"192.168.1.1\\\"},{\\\"moduleNumber\\\":\\\"1\\\",\\\"terminalNumber\\\":\\\"S00010101010\\\",\\\"progName\\\":\\\"超薄款\\\",\\\"idCard\\\":\\\"\\\",\\\"remark\\\":\\\"\\\",\\\"isOnline\\\":1,\\\"tenementName\\\":\\\"\\\",\\\"firmwareUpdate\\\":\\\"\\\",\\\"defenseData\\\":{\\\"moduleNumber\\\":1,\\\"isRoad\\\":[0,0,0,0,0,0,0,0],\\\"isSecret\\\":[0,0,0,0,0,0,0,0],\\\"alarmStatus\\\":[0,0,0,0,0,0,0,0],\\\"isOk\\\":[0,0,0,0,0,0,0,0],\\\"protectionStatus\\\":[0,0,0,0,0,0,0,0],\\\"outDelayed\\\":[0,0,30,30,0,0,0,0],\\\"is24\\\":[1,1,0,0,0,0,0,0],\\\"inDelayed\\\":[0,0,30,30,0,0,0,0]},\\\"deployType\\\":\\\"未布防\\\",\\\"serverIpAddress\\\":\\\"192.168.1.222\\\",\\\"cellphone\\\":\\\"\\\",\\\"id\\\":2639,\\\"email\\\":\\\"\\\",\\\"terminalDesc\\\":\\\"0001栋01单元01楼01号房0设备\\\",\\\"ipAddress\\\":\\\"192.168.1.200\\\",\\\"updateUser\\\":1,\\\"telephone\\\":\\\"\\\",\\\"updateTime\\\":1728499091000,\\\"progVersion\\\":\\\"MaB10IS02-3002B7\\\",\\\"subnetMask\\\":\\\"255.255.255.0\\\",\\\"terminalType\\\":\\\"S\\\",\\\"macAddress\\\":\\\"00020300016A\\\",\\\"deleted\\\":false,\\\"createTime\\\":1711617153000,\\\"createUser\\\":0,\\\"gatewayAddress\\\":\\\"192.168.1.1\\\"},{\\\"terminalNumber\\\":\\\"Z00010000000\\\",\\\"progName\\\":\\\"标准版\\\",\\\"idCard\\\":\\\"\\\",\\\"ipAddress\\\":\\\"192.168.1.203\\\",\\\"telephone\\\":\\\"\\\",\\\"remark\\\":\\\"\\\",\\\"isOnline\\\":1,\\\"updateTime\\\":1728499091000,\\\"progVersion\\\":\\\"McB10IZ01-3007B4\\\",\\\"tenementName\\\":\\\"\\\",\\\"subnetMask\\\":\\\"255.255.255.0\\\",\\\"firmwareUpdate\\\":\\\"\\\",\\\"terminalType\\\":\\\"Z\\\",\\\"macAddress\\\":\\\"0050C84C7025\\\",\\\"deleted\\\":false,\\\"createTime\\\":1711616860000,\\\"serverIpAddress\\\":\\\"192.168.1.222\\\",\\\"cellphone\\\":\\\"\\\",\\\"createUser\\\":1,\\\"id\\\":2640,\\\"gatewayAddress\\\":\\\"192.168.1.1\\\",\\\"email\\\":\\\"\\\",\\\"terminalDesc\\\":\\\"0001号中心机\\\"}]}\",\"Code\":0},\"Id\":\"869026153396965376\",\"Code\":\"0\"},\"RequestId\":\"2de48529b5774feeb77ca3a50aa09805\"}";
        IotResponseVO iotResponseVO = JSONObject.parseObject(jsonStr, IotResponseVO.class);
        String dataStr = iotResponseVO.getData();
        IotResponseDataVO dataVO = JSONObject.parseObject(dataStr, IotResponseDataVO.class);
        String data2Str = dataVO.getData();
        IotResponseDataInfoVO iotResponseDataInfoVO = JSONObject.parseObject(data2Str, IotResponseDataInfoVO.class);
        String datasStr = iotResponseDataInfoVO.getDatas();
        IotDeviceInfoPageVO iotDeviceInfoPageVO = JSONObject.parseObject(datasStr, IotDeviceInfoPageVO.class);
        String rowsStr = iotDeviceInfoPageVO.getRows();
        JSONArray jsonArray = JSONArray.parseArray(rowsStr);
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject1 = jsonArray.getJSONObject(i);
            IotDeviceInfoVO iotDeviceInfoVO = JSONObject.parseObject(jsonObject1.toString(), IotDeviceInfoVO.class);
            System.out.println(iotDeviceInfoVO.getTerminalNumber());
        }
    } */

}
