package org.springblade.device.feign;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import javax.validation.Valid;

import org.springblade.common.constant.CommonConstant;
import org.springblade.common.constant.OperationConstant;
import org.springblade.common.utils.JsonUtils;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.device.dto.DispatchTask;
import org.springblade.device.dto.UserInfoDto;
import org.springblade.device.service.MsgPublishService;
import org.springblade.estate.entity.AccessFacePushRecords;
import org.springblade.estate.feign.IAccessFacePushRecordsClient;
import org.springblade.estate.vo.AccessFacePushRecordsVO;
import org.springblade.common.constant.Instruct;
import org.springblade.system.expand.feign.IOrgPositionClient;
import org.springblade.system.expand.util.QueryWrapperUtil;
import org.springblade.third.doordevice.feign.IDoorDeviceButtClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;
import org.springblade.device.entity.DoorDevice;
import org.springblade.device.vo.DoorDeviceVO;
import org.springblade.device.wrapper.DoorDeviceWrapper;
import org.springblade.device.service.IDoorDeviceService;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  client
 *
 * @author lianghanqiang
 * @since 2021-04-19
 */

@AllArgsConstructor
@RestController
@RequestMapping("/feign/doordevice")

public class DoorDeviceClient implements IDoorDeviceClient {

    private final IDoorDeviceService doorDeviceService;
    private final IOrgPositionClient orgPositionClient;
    private final IDoorDeviceButtClient doorDeviceButtClient;

        /**
     * 详情
     */
    @Override
    @GetMapping("/detail")
    public DoorDeviceVO detail(@SpringQueryMap DoorDevice doorDevice) {
        DoorDevice detail = doorDeviceService.getOne(Condition.getQueryWrapper(doorDevice));
        return DoorDeviceWrapper.build().entityVO(detail);
        }

	@Override
	@GetMapping("/getById")
	public DoorDevice getById(@RequestParam Long id) {
		return this.doorDeviceService.getById(id);
	}

	/**
     * 查询
     */
    @Override
    @GetMapping("/list")
    public List<DoorDeviceVO> list(@SpringQueryMap DoorDevice doorDevice) {
		LambdaQueryWrapper<DoorDevice> queryWrapper = new QueryWrapperUtil<DoorDevice>().getBasicQueryWrapper(DoorDevice::getTenantId, doorDevice, AuthUtil.getUser(), orgPositionClient);
		return DoorDeviceWrapper.build().listVO(doorDeviceService.list(queryWrapper));
        }

	@Override
	@GetMapping("/listMap")
	public List<DoorDeviceVO> listMap(@RequestParam Map<String, Object> doorDevice) {
		LambdaQueryWrapper<DoorDevice> queryWrapper = new QueryWrapperUtil<DoorDevice>().getBasicQueryWrapperByMap(DoorDevice::getTenantId, doorDevice, new DoorDevice(), AuthUtil.getUser(), orgPositionClient);
		return DoorDeviceWrapper.build().listVO(doorDeviceService.list(queryWrapper.eq(DoorDevice::getTenantId,AuthUtil.getUser().getTenantId())));
	}


	/**
     * 新增
     */
    @Override
    @PostMapping("/save")
    public boolean save(@Valid @RequestBody DoorDevice doorDevice) {
        return doorDeviceService.save(doorDevice);
        }

    /**
     * 修改
     */
    @Override
    @PostMapping("/update")
    public boolean update(@Valid @RequestBody DoorDevice doorDevice) {
        return doorDeviceService.updateById(doorDevice);
        }

    /**
     * 新增或修改
     */
    @Override
    @PostMapping("/submit")
    public boolean submit(@Valid @RequestBody DoorDevice doorDevice) {
        return doorDeviceService.saveOrUpdate(doorDevice);
        }


    /**
     * 删除
     */
    @Override
    @PostMapping("/remove")
    public boolean remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
        return doorDeviceService.deleteLogic(Func.toLongList(ids));
        }

	@Override
	@PostMapping(value = "/device/pushUserFace/{operType}")
	public R pushUserFace(@RequestBody DispatchTask task, @PathVariable(value = "operType") Integer operType) {
		Assert.notNull(task.getXqId(),"小区Id不能为空");
		Assert.notNull(task.getData(),"人脸信息不能为空");
		ObjectMapper objectMapper = new ObjectMapper();
		Map<String,Object> userInfoDto = objectMapper.convertValue(task.getData(), Map.class);
		DoorDevice searchEntity = new DoorDevice();
		List<DoorDevice> deviceList = new ArrayList<>();
		if(task.getXqId() != null){
			searchEntity.setResidentialId(task.getXqId());
//			searchEntity.setHaveFace(1);//1标识支持人脸识别的设备
		}
		List<DoorDevice> residentialDeviceList = this.doorDeviceService.list(Condition.getQueryWrapper(searchEntity));
		if(task.getUnitId() != null){
			searchEntity.setResidentialId(null);
			searchEntity.setUnitId(task.getUnitId());
		}
		List<DoorDevice> unitDeviceList = this.doorDeviceService.list(Condition.getQueryWrapper(searchEntity));
		deviceList.addAll(residentialDeviceList);
		deviceList.addAll(unitDeviceList);
		if(deviceList == null || deviceList.size() < 0){
			return R.success("小区下无人脸机，无需下发人脸");
		}
		R result = null;
		if(operType == 1){ //新增人脸
			result = doorDeviceButtClient.addUser(deviceList, userInfoDto);
		}else if(operType == 2){ //删除人脸
			result = doorDeviceButtClient.delUser(deviceList, userInfoDto);
		}
		return result;
	}

	@Override
	@GetMapping("/getListByMacAddresses")
	public List<DoorDevice> getListByMacAddresses(List<String> macAddresses) {
		List<DoorDevice> doorDevices = this.doorDeviceService.getBaseMapper().selectList(new QueryWrapper<>(new DoorDevice()).lambda().in(DoorDevice::getSerialNum, macAddresses));
		return doorDevices;
	}

	@Override
	@GetMapping("/getListByResidentialAndUnit/{residentialId}/{unitId}")
	public List<DoorDeviceVO> getListByResidentialAndUnit(@PathVariable("residentialId") Long residentialId,@PathVariable("unitId") Long unitId, @RequestParam(value = "localType", required = false) Integer localType) {
		LambdaQueryWrapper<DoorDevice> doorDeviceLambdaQueryWrapper = new QueryWrapper<>(new DoorDevice()).lambda().eq(DoorDevice::getResidentialId, residentialId)
			.or().eq(DoorDevice::getUnitId, unitId).eq(localType != null, DoorDevice::getLocalType, localType);
		return DoorDeviceWrapper.build().listVO(this.doorDeviceService.list(doorDeviceLambdaQueryWrapper));
	}

	@Override
	@GetMapping("/getListByAgencyAndResidential/{agencyId}/{residentialId}")
	public List<DoorDeviceVO> getListByAgencyAndResidential(@PathVariable("agencyId") Long agencyId,@PathVariable("residentialId") Long residentialId) {
		LambdaQueryWrapper<DoorDevice> doorDeviceLambdaQueryWrapper = new QueryWrapper<>(new DoorDevice()).lambda().eq(DoorDevice::getAgencyId, agencyId)
			.or().eq(DoorDevice::getResidentialId, residentialId);
		return DoorDeviceWrapper.build().listVO(this.doorDeviceService.list(doorDeviceLambdaQueryWrapper));
	}

	@Override
	@GetMapping("/getBySerialNum")
	public DoorDeviceVO getBySerialNum(@RequestParam String serialNum) {
		DoorDevice doorDevice = this.doorDeviceService.getBySerialNum(serialNum);
		return DoorDeviceWrapper.build().entityVO(doorDevice);
	}

	@Override
	@GetMapping("/heartbeat")
	public R heartbeat(@RequestParam String serialNum) {
    	return this.doorDeviceService.heartbeat(serialNum);
	}

	@Override
	@GetMapping("/getListByAgencyId")
	public List<DoorDevice> getListByAgencyId(@RequestParam Long agencyId) {
		LambdaQueryWrapper<DoorDevice> doorDeviceLambdaQueryWrapper = new QueryWrapper<>(new DoorDevice()).lambda().eq(DoorDevice::getAgencyId, agencyId);
		return this.doorDeviceService.list(doorDeviceLambdaQueryWrapper);
	}

	@Override
	@PostMapping("/remoteOpenDoor")
	public R remoteOpenDoor(String userId, String userName, String userType, String serialNum, String factory, boolean isOpen) {
		return this.doorDeviceService.remoteOpenDoor(userId, userName, userType, serialNum, factory, isOpen);
	}

	@Override
	@PostMapping("/listByIds")
	public List<DoorDevice> listByIds(@RequestParam(value = "ids") String ids) {
		List<String> idList = Func.toStrList(ids);
		return this.doorDeviceService.listByIds(idList);
	}


}
