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

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuchen.saas.park.api.dto.park.IoTEvent;
import com.yuchen.saas.park.api.entity.elevator.SaasParkElevatorManageLocationEntity;
import com.yuchen.saas.park.api.entity.elevator.SaasParkElevatorMonitorAlarmRecords;
import com.yuchen.saas.park.api.entity.elevator.SaasParkElevatorPerson;
import com.yuchen.saas.park.api.entity.elevator.SaasParkElevatorRecordInoutRecordsEntity;
import com.yuchen.saas.park.api.entity.park.PmgBatParkInfo;
import com.yuchen.saas.park.api.entity.pldoor.PlDoorInoutRecode;
import com.yuchen.saas.park.api.entity.pldoor.PlDoorPoint;
import com.yuchen.saas.park.api.entity.pldoor.PlDoorUserPointSet;
import com.yuchen.saas.park.api.entity.property.PropertyBuildingUnit;
import com.yuchen.saas.park.api.entity.property.PropertyBuildings;
import com.yuchen.saas.park.api.request.ElevatorInOrOutRecordsRequest;
import com.yuchen.saas.park.api.response.ElevatorInOrOutRecordsResponse;
import com.yuchen.saas.park.api.response.SaasParkElevatorMonitorAlarmRecordsResponse;
import com.yuchen.saas.park.api.vo.elevator.ElevatorPersonVO;
import com.yuchen.saas.park.service.controller.elevator.SaasParkElevatorPersonController;
import com.yuchen.saas.park.service.mapper.elevator.SaasParkElevatorManageLocationMapper;
import com.yuchen.saas.park.service.mapper.elevator.SaasParkElevatorRecordInoutRecordsMapper;
import com.yuchen.saas.park.service.mapper.property.PropertyBuildingUnitMapper;
import com.yuchen.saas.park.service.mapper.property.PropertyBuildingsMapper;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import com.yuchen.saas.park.service.service.elevator.ISaasParkElevatorPersonService;
import com.yuchen.saas.park.service.service.elevator.ISaasParkElevatorRecordInoutRecordsService;
import com.yuchen.saas.parking.api.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.mp.support.Condition;
import org.nest.springwrap.core.mp.support.Query;
import org.nest.springwrap.core.secure.ContextUser;
import org.nest.springwrap.core.secure.utils.AuthUtil;
import org.nest.springwrap.core.tool.api.R;
import org.nest.springwrap.core.tool.utils.Func;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * saas_park_elevator_record_inout_records 服务实现类
 * </p>
 *
 * @author baichaojie
 * @since 2024-06-25
 */
@Service
@Slf4j
public class SaasParkElevatorRecordInoutRecordsServiceImpl extends BaseServiceImpl<SaasParkElevatorRecordInoutRecordsMapper, SaasParkElevatorRecordInoutRecordsEntity> implements ISaasParkElevatorRecordInoutRecordsService {

    @Autowired
    private PmgBatParkInfoService pmgBatParkInfoService;

    @Resource
    private ISaasParkElevatorPersonService saasParkElevatorPersonService;

    @Autowired
    private SaasParkElevatorManageLocationMapper saasParkElevatorManageLocationMapper;

    @Autowired
    private PropertyBuildingUnitMapper propertyBuildingUnitMapper;

    // 电梯进出记录上报(通行事件上报)
    private final String eventRecord = "eventRecord";


    @Resource
    private PropertyBuildingsMapper propertyBuildingsMapper;

    @Override
    public R<IPage<ElevatorInOrOutRecordsResponse>> elevatorInOrOutRecords(ElevatorInOrOutRecordsRequest qryDto, Query query) {

        Page<SaasParkElevatorRecordInoutRecordsEntity> page = new Page<>(query.getCurrent(), query.getSize());
        LambdaQueryWrapper<SaasParkElevatorRecordInoutRecordsEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Func.isNotEmpty(qryDto.getParkId()), SaasParkElevatorRecordInoutRecordsEntity::getParkId, qryDto.getParkId());
        queryWrapper.eq(Func.isNotEmpty(qryDto.getBuildingId()), SaasParkElevatorRecordInoutRecordsEntity::getBuildingId, qryDto.getBuildingId());
        queryWrapper.eq(Func.isNotEmpty(qryDto.getUnitId()), SaasParkElevatorRecordInoutRecordsEntity::getUnitId, qryDto.getUnitId());
        queryWrapper.like(Func.isNotBlank(qryDto.getPersonName()), SaasParkElevatorRecordInoutRecordsEntity::getPersonName, qryDto.getPersonName());
        queryWrapper.like(Func.isNotBlank(qryDto.getElevatorName()), SaasParkElevatorRecordInoutRecordsEntity::getPersonName, qryDto.getElevatorName());
        queryWrapper.like(Func.isNotEmpty(qryDto.getPersonType()), SaasParkElevatorRecordInoutRecordsEntity::getPersonType, qryDto.getPersonType());
        queryWrapper.eq(Func.isNotEmpty(qryDto.getAuthMethod()), SaasParkElevatorRecordInoutRecordsEntity::getAuthMethod, qryDto.getAuthMethod());
        queryWrapper.le(Func.isNotEmpty(qryDto.getPassTime()), SaasParkElevatorRecordInoutRecordsEntity::getPassTime, qryDto.getPassTime());
        queryWrapper.orderByDesc(SaasParkElevatorRecordInoutRecordsEntity::getCreateTime);

        IPage<SaasParkElevatorRecordInoutRecordsEntity> pages = this.page(page, queryWrapper);
        List<SaasParkElevatorRecordInoutRecordsEntity> saasParkElevatorRecordInoutRecordsEntityList = pages.getRecords();

        if (saasParkElevatorRecordInoutRecordsEntityList.isEmpty()) {
            return R.data(Condition.getPage(query));
        }

        IPage<ElevatorInOrOutRecordsResponse> pageVo = new Page(pages.getCurrent(), pages.getSize(), pages.getTotal());
        List<ElevatorInOrOutRecordsResponse> records = this.listVO(pages.getRecords());
        pageVo.setRecords(records);
        return R.data(pageVo);

    }


    public List<ElevatorInOrOutRecordsResponse> listVO(List<SaasParkElevatorRecordInoutRecordsEntity> listRecords) {
        return (List) listRecords.stream().map(entity -> {
            ElevatorInOrOutRecordsResponse elevatorInOrOutRecordsResponse = detail(entity.getId(), entity).getData();
            return elevatorInOrOutRecordsResponse;
        }).collect(Collectors.toList());

    }


    public R<ElevatorInOrOutRecordsResponse> detail(Long id, SaasParkElevatorRecordInoutRecordsEntity saasParkElevatorRecordInoutRecordsEntity) {
        ElevatorInOrOutRecordsResponse elevatorInOrOutRecordsResponse = new ElevatorInOrOutRecordsResponse();
        BeanUtils.copyProperties(saasParkElevatorRecordInoutRecordsEntity, elevatorInOrOutRecordsResponse);

        PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(saasParkElevatorRecordInoutRecordsEntity.getParkId());
        if (Func.isNotEmpty(parkInfo)) {
            elevatorInOrOutRecordsResponse.setParkName(parkInfo.getParkName());
        }


        PropertyBuildings propertyBuildings = propertyBuildingsMapper.selectById(saasParkElevatorRecordInoutRecordsEntity.getBuildingId());
        if (propertyBuildings != null) {
            elevatorInOrOutRecordsResponse.setBuildingName(propertyBuildings.getBuildingName());
        }

        PropertyBuildingUnit propertyBuildingUnit = propertyBuildingUnitMapper.selectById(saasParkElevatorRecordInoutRecordsEntity.getUnitId());
        if (propertyBuildingUnit != null) {
            elevatorInOrOutRecordsResponse.setUnitName(propertyBuildingUnit.getUnitName());
        }

        ElevatorPersonVO person = saasParkElevatorPersonService.getDetailById(saasParkElevatorRecordInoutRecordsEntity.getPersonId());

        if (person != null) {
            //人员类型
            if (person.getUserType() != null) {
                elevatorInOrOutRecordsResponse.setPersonType(Integer.parseInt(person.getUserType().toString()));
            }
            //人脸照片(抓拍的还是录入的)?先用录入的,抓拍的IOT没上报
            elevatorInOrOutRecordsResponse.setFaceImg(person.getUserFaceUrl());
        }
        return R.data(elevatorInOrOutRecordsResponse);
    }


    @Override
    public boolean receiveIotEvent(String jsonObjectContent) throws Exception {
        // 处理接收到的iot事件
        log.info("====== 接收到的iot上报设备事件:{}", jsonObjectContent);
        if (Func.isEmpty(jsonObjectContent)) {
            log.error("====== 接收到的iot上报事件为空");
            return false;
        }
        IoTEvent ioTEvent = JSON.parseObject(jsonObjectContent, IoTEvent.class);
        if (Func.isEmpty(ioTEvent) || Func.isEmpty(ioTEvent.getIdentifier())) {
            throw new RuntimeException("====== 接收到的iot上报事件为空");
        }
        String identifier = ioTEvent.getIdentifier();
        if (identifier.equals(eventRecord)) {
            //电梯进出记录上报(通行事件上报)
            saveOpenDoorUpload(ioTEvent, ioTEvent.getDeviceName());
        }
        return true;
    }


    /**
     * IOT上报电梯记录
     *
     * @param ioTEvent
     */
    private void saveOpenDoorUpload(IoTEvent ioTEvent, String deviceName) {

        //根据iot传过来的设备name获取门禁点里对应的设备

        SaasParkElevatorManageLocationEntity saasParkElevatorManageLocationEntity = saasParkElevatorManageLocationMapper.selectOne(Wrappers.<SaasParkElevatorManageLocationEntity>lambdaQuery()
                .eq(SaasParkElevatorManageLocationEntity::getDeviceName, deviceName).last("limit 1"));

        if (saasParkElevatorManageLocationEntity == null) {
            return;
        }


        if (Func.isNotEmpty(ioTEvent) && Func.isNotEmpty(ioTEvent.getOut())) {
            Map<String, Object> out = ioTEvent.getOut();
            Map<String, Object> outMap = (Map<String, Object>) out.get("data");
            SaasParkElevatorRecordInoutRecordsEntity saasParkElevatorRecordInoutRecordsEntity = new SaasParkElevatorRecordInoutRecordsEntity();

            //认证设备ID
            String verifyDeviceID = outMap.get("verifyDeviceID").toString();
            //事件上报时间
            String recordTime = outMap.get("recordTime").toString();
            //验证方式(0人脸 1刷卡 2二维码)
            String verifyMode = outMap.get("verifyMode").toString();
            //人员ID
            String personID = outMap.get("personID").toString();
            //设备ID
            String deviceID = outMap.get("deviceID").toString();

            saasParkElevatorRecordInoutRecordsEntity.setPassTime(DateUtils.parseDate("yyyy-MM-dd HH:mm:ss", recordTime));
            saasParkElevatorRecordInoutRecordsEntity.setPersonId(Long.parseLong(personID));

            SaasParkElevatorPerson person = saasParkElevatorPersonService.getOne(new LambdaQueryWrapper<SaasParkElevatorPerson>().eq(SaasParkElevatorPerson::getId, Long.parseLong(personID)));
            if (person != null) {
                saasParkElevatorRecordInoutRecordsEntity.setPersonName(person.getUserName());
            }

            saasParkElevatorRecordInoutRecordsEntity.setAuthMethod((int) Double.parseDouble(verifyMode));

            saasParkElevatorRecordInoutRecordsEntity.setElevatorId(saasParkElevatorManageLocationEntity.getId());
            saasParkElevatorRecordInoutRecordsEntity.setElevatorName(saasParkElevatorManageLocationEntity.getElevatorName());
            saasParkElevatorRecordInoutRecordsEntity.setBuildingId(saasParkElevatorManageLocationEntity.getBuildingId());
            saasParkElevatorRecordInoutRecordsEntity.setUnitId(saasParkElevatorManageLocationEntity.getUnitId());
            saasParkElevatorRecordInoutRecordsEntity.setParkId(saasParkElevatorManageLocationEntity.getParkId());


            this.saveOrUpdate(saasParkElevatorRecordInoutRecordsEntity);


        }
    }


}
