package org.springblade.third.doordevice.feign;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.constant.CommonConstant;
import org.springblade.common.constant.OperationConstant;
import org.springblade.common.utils.JsonUtils;
import org.springblade.community.entity.Residential;
import org.springblade.community.feign.IResidentialClient;
import org.springblade.core.tool.api.R;
import org.springblade.device.entity.DoorDevice;
import org.springblade.device.feign.IDoorDeviceClient;
import org.springblade.estate.entity.AccessRecord;
import org.springblade.estate.feign.IAccessRecordClient;
import org.springblade.resource.feign.IOssEndpointClient;
import org.springblade.common.beans.ApiResultBean;
import org.springblade.third.doordevice.entity.InstructPublishLog;
import org.springblade.third.doordevice.entity.QinlinApiLog;
import org.springblade.third.doordevice.entity.qinlin.*;
import org.springblade.third.doordevice.feign.qinlin.IQLinClient;
import org.springblade.common.constant.Instruct;
import org.springblade.third.doordevice.utils.QinLinHttpUtil;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created By lidexi in 2021/4/27
 **/
@Slf4j
@RestController
@RequiredArgsConstructor
public class QLinClient implements IQLinClient {

	private final IQinlinApiLogClient qinlinApiLogClient;
	private final IDoorDeviceClient doorDeviceFeign;
	private final IInstructPublishLogClient instructPublishLogClient;
	private final IAccessRecordClient accessRecordClient;
	private final IResidentialClient residentialClient;
	private final IOssEndpointClient ossEndpointClient;
	private final QinLinHttpUtil qinLinHttpUtil;
	@Override
	@PostMapping("/qinLin/addUser")
	public R<String> addUser(@RequestBody QLinUser qLinUser) {
		R<String> resultBean = null;
		InstructPublishLog instructPublishLog = new InstructPublishLog();
		instructPublishLog.setCreateTime(new Date());
		ApiResultBean apiResultBean = null;
		try {
			String expires = qLinUser.getExpires();
			if(!StringUtils.hasText(expires)){
				Calendar cd = Calendar.getInstance();
				cd.setTime(new Date());
				cd.add(Calendar.YEAR, 10);
				Date expireDate = cd.getTime();
				String strDateFormat = "yyyy-MM-dd HH:mm:ss";
				SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
				qLinUser.setExpires(sdf.format(expireDate));
			}
			apiResultBean = qinLinHttpUtil.addUser(qLinUser);
			QinlinApiLog qLinApiLog = new QinlinApiLog();
			qLinApiLog.setCode(apiResultBean.getCode());
			qLinApiLog.setMessage(apiResultBean.getMessage());
			qLinApiLog.setReqData(JsonUtils.objectToJson(qLinUser));
			qLinApiLog.setData(JsonUtils.objectToJson(apiResultBean.getData()));
			qLinApiLog.setMethod("新增用户");
			this.qinlinApiLogClient.save(qLinApiLog);
			boolean addSuccess = apiResultBean.getSuccess();
			String[] split = qLinUser.getDeviceIds().split(",");
			List<DoorDevice> deviceList = doorDeviceFeign.getListByMacAddresses(Arrays.asList(split));

			String data = JsonUtils.objectToJson(qLinUser);
			instructPublishLog.setPublishData(data);
			instructPublishLog.setSerialNumber(qLinUser.getDeviceIds());
			instructPublishLog.setStatus(OperationConstant.TWO);
			if(addSuccess){
				instructPublishLog.setHandleStatus(OperationConstant.TWO);
				if(qLinUser.getUserId().startsWith(CommonConstant.UserFlag.SERVER_USER_FLAG.getValue())){
					instructPublishLog.setErrorMsg("添加/更新服务员成功");
					resultBean = R.success("添加服务员成功");
				}else{
					instructPublishLog.setErrorMsg("添加/更新住户成功");
					resultBean = R.success("添加住户成功");
				}
			}else{
				instructPublishLog.setHandleStatus(OperationConstant.THREE);
				if(qLinUser.getUserId().startsWith(CommonConstant.UserFlag.SERVER_USER_FLAG.getValue())){
					instructPublishLog.setErrorMsg("添加/更新服务员失败");
					resultBean = R.fail("添加服务员失败");
				}else{
					instructPublishLog.setErrorMsg("添加/更新住户失败");
					resultBean = R.fail("添加住户失败");
				}
			}
			instructPublishLog.setInstructCode(Instruct.add_user_face.getCode());
			instructPublishLog.setInstructDescribe(Instruct.add_user_face.getDescribe());
			instructPublishLog.setLastModifyTime(new Date());
			this.instructPublishLogClient.save(instructPublishLog);
		}catch (Exception e){
			QinlinApiLog qLinApiLog = new QinlinApiLog();
			qLinApiLog.setCode(apiResultBean.getCode());
			qLinApiLog.setMessage(e.getMessage());
			qLinApiLog.setData(JsonUtils.objectToJson(apiResultBean.getData()));
			qLinApiLog.setMethod("新增用户异常");
			this.qinlinApiLogClient.save(qLinApiLog);
			resultBean = R.fail("新增用户异常");
		}
		return resultBean;
	}

	@Override
	@PostMapping("/qinLin/deleteUser")
	public R<String> deleteUser(@RequestBody QLinUser qLinUser) {
		R<String> resultBean = null;
		ApiResultBean apiResultBean = qinLinHttpUtil.deleteUser(qLinUser);
		QinlinApiLog qLinApiLog = new QinlinApiLog();
		qLinApiLog.setCode(apiResultBean.getCode());
		qLinApiLog.setMessage(apiResultBean.getMessage());
		qLinApiLog.setReqData(JsonUtils.objectToJson(qLinUser));
		qLinApiLog.setData(JsonUtils.objectToJson(apiResultBean.getData()));
		qLinApiLog.setMethod("删除用户");
		this.qinlinApiLogClient.save(qLinApiLog);
		boolean deleteSuccess = apiResultBean.getCode().equals(OperationConstant.ZERO);
		DoorDevice searchEntity = new DoorDevice();
		searchEntity.setSerialNum(qLinUser.getDeviceIds());
		DoorDevice device = doorDeviceFeign.detail(searchEntity);
		String data = JsonUtils.objectToJson(qLinUser);
		InstructPublishLog instructPublishLog = new InstructPublishLog();
		instructPublishLog.setCreateTime(new Date());
		instructPublishLog.setPublishData(data);
		instructPublishLog.setStatus(OperationConstant.TWO);
		instructPublishLog.setSerialNumber(device.getSerialNum());
		if(deleteSuccess){
			instructPublishLog.setHandleStatus(OperationConstant.TWO);
			if(qLinUser.getUserId().startsWith(CommonConstant.UserFlag.SERVER_USER_FLAG.getValue())){
				instructPublishLog.setErrorMsg("删除服务员成功");
				resultBean = R.success("删除服务员成功");
			}else{
				instructPublishLog.setErrorMsg("删除住户成功");
				resultBean = R.data("删除住户成功");
			}
		}else{
			instructPublishLog.setHandleStatus(OperationConstant.THREE);
			if(qLinUser.getUserId().startsWith(CommonConstant.UserFlag.SERVER_USER_FLAG.getValue())){
				instructPublishLog.setErrorMsg("删除服务员失败");
				resultBean = R.fail("删除服务员失败");
			}else{
				instructPublishLog.setErrorMsg("删除住户失败");
				resultBean = R.fail("删除住户失败");
			}
		}
		instructPublishLog.setInstructCode(Instruct.delete_user.getCode());
		instructPublishLog.setInstructDescribe(Instruct.delete_user.getDescribe());
		instructPublishLog.setLastModifyTime(new Date());
		this.instructPublishLogClient.save(instructPublishLog);
		return resultBean;
	}

	@Override
	@PostMapping("/qinLin/deleteUserPermission")
	public R<String> deleteUserPermission(@RequestBody QLinUserDevice qLinUserDevice) {
		R<String> resultBean = null;
		ApiResultBean apiResultBean = qinLinHttpUtil.deleteUserPermission(qLinUserDevice);
		QinlinApiLog qLinApiLog = new QinlinApiLog();
		qLinApiLog.setCode(apiResultBean.getCode());
		qLinApiLog.setMessage(apiResultBean.getMessage());
		qLinApiLog.setReqData(JsonUtils.objectToJson(qLinUserDevice));
		qLinApiLog.setData(JsonUtils.objectToJson(apiResultBean.getData()));
		qLinApiLog.setMethod("删除用户权限");
		this.qinlinApiLogClient.save(qLinApiLog);
		boolean deleteSuccess = apiResultBean.getCode().equals(OperationConstant.ZERO);
		DoorDevice searchEntity = new DoorDevice();
		searchEntity.setSerialNum(qLinUserDevice.getDeviceIds());
		DoorDevice device = doorDeviceFeign.detail(searchEntity);
		InstructPublishLog instructPublishLog = new InstructPublishLog();
		instructPublishLog.setCreateTime(new Date());
		String data = JsonUtils.objectToJson(qLinUserDevice);
		instructPublishLog.setPublishData(data);
		instructPublishLog.setSerialNumber(device.getSerialNum());
		instructPublishLog.setStatus(OperationConstant.TWO);
		if(deleteSuccess){
			instructPublishLog.setHandleStatus(OperationConstant.TWO);
			if(qLinUserDevice.getUserId().startsWith(CommonConstant.UserFlag.SERVER_USER_FLAG.getValue())){
				instructPublishLog.setErrorMsg("删除服务员人脸权限成功");
				resultBean = R.success("删除服务员人脸权限成功");
			}else{
				instructPublishLog.setErrorMsg("删除住户人脸权限成功");
				resultBean = R.success("删除住户人脸权限成功");
			}
		}else{
			instructPublishLog.setHandleStatus(OperationConstant.THREE);
			if(qLinUserDevice.getUserId().startsWith(CommonConstant.UserFlag.SERVER_USER_FLAG.getValue())){
				instructPublishLog.setErrorMsg("删除服务员人脸权限失败");
				resultBean = R.fail("删除服务员人脸权限失败");
			}else{
				instructPublishLog.setErrorMsg("删除住户人脸权限失败");
				resultBean = R.fail("删除住户人脸权限失败");
			}
		}
		instructPublishLog.setInstructCode(Instruct.delete_user_face.getCode());
		instructPublishLog.setInstructDescribe(Instruct.delete_user_face.getDescribe());
		instructPublishLog.setLastModifyTime(new Date());
		this.instructPublishLogClient.save(instructPublishLog);
		return resultBean;
	}

	@Override
	@PostMapping("/qinLin/deleteDevice")
	public R<String> deleteDevice(@RequestBody QLinDevice qLinDevice) {
		return R.data("");
	}

	@Override
	@PostMapping("/qinLin/getDeviceInfo")
	public R<String> getDeviceInfo(@RequestBody QLinDevice qLinDevice) {
		return R.data("");
	}

	@Override
	@PostMapping("/qinLin/remoteOpenDoor")
	public R remoteOpenDoor(@RequestBody QLinUserDevice qLinUserDevice) {
		R<String> resultBean = null;
		ApiResultBean apiResultBean = qinLinHttpUtil.remoteOpenDoor(qLinUserDevice);
		QinlinApiLog qLinApiLog = new QinlinApiLog();
		qLinApiLog.setCode(apiResultBean.getCode());
		qLinApiLog.setMessage(apiResultBean.getMessage());
		qLinApiLog.setReqData(JsonUtils.objectToJson(qLinUserDevice));
		qLinApiLog.setData(JsonUtils.objectToJson(apiResultBean.getData()));
		qLinApiLog.setMethod("远程开门");
		this.qinlinApiLogClient.save(qLinApiLog);
		boolean openSuccess = apiResultBean.getCode().equals(OperationConstant.ZERO);
		DoorDevice searchEntity = new DoorDevice();
		searchEntity.setSerialNum(qLinUserDevice.getDeviceId());
		DoorDevice device = doorDeviceFeign.detail(searchEntity);
		String data = JsonUtils.objectToJson(qLinUserDevice);
		InstructPublishLog instructPublishLog = new InstructPublishLog();
		instructPublishLog.setCreateTime(new Date());
		instructPublishLog.setSerialNumber(device.getSerialNum());
		instructPublishLog.setPublishData(data);
		instructPublishLog.setStatus(OperationConstant.TWO);
		if(openSuccess){
			instructPublishLog.setHandleStatus(OperationConstant.TWO);
			instructPublishLog.setErrorMsg("开门成功");
			resultBean = R.success("远程开门成功");
		}else{
			instructPublishLog.setHandleStatus(OperationConstant.THREE);
			instructPublishLog.setErrorMsg("开门失败");
			resultBean = R.fail(apiResultBean.getMessage());
		}
		instructPublishLog.setInstructCode(Instruct.open_door.getCode());
		instructPublishLog.setInstructDescribe(Instruct.open_door.getDescribe());
		instructPublishLog.setLastModifyTime(new Date());
		if(openSuccess){
			this.instructPublishLogClient.save(instructPublishLog);
		}
		return resultBean;
	}

	@Override
	@PostMapping("/qinLin/getLogs")
	public R<String> getLogs(@RequestBody QLinQuery qLinQuery) {
		ApiResultBean<List<QLinOpenRecord>> apiResultBean = qinLinHttpUtil.getLogs(qLinQuery, ossEndpointClient);
		QinlinApiLog qLinApiLog = new QinlinApiLog();
		qLinApiLog.setCode(apiResultBean.getCode());
		qLinApiLog.setMessage(apiResultBean.getMessage());
		qLinApiLog.setReqData(JsonUtils.objectToJson(qLinQuery));
		qLinApiLog.setData(JsonUtils.objectToJson(apiResultBean.getData()));
		qLinApiLog.setMethod("获取开门日志");
		this.qinlinApiLogClient.save(qLinApiLog);
		List<QLinOpenRecord> list = apiResultBean.getData();
		if(list.size() > 0){
			list.forEach(data -> {
				//是因为亲邻的日志接口，如果传deviceIds过去，它是会把所有日志都拿回来。所以如果调4次接口，就会重复返回所有日志
				//但实际上只有个别设备才会有记录。
				if(qLinQuery.getDeviceIds().contains(data.getDeviceId())){
					String serialNumber = data.getDeviceId();
					DoorDevice searchEntity = new DoorDevice();
					searchEntity.setSerialNum(serialNumber);
					DoorDevice dbDevice = this.doorDeviceFeign.detail(searchEntity);
					if(dbDevice != null){
						AccessRecord records = new AccessRecord();
						String openType = data.getOpenType();
						if(openType.equals(OperationConstant.ONE + "")){
							records.setOpenType(OperationConstant.ZERO); //人脸开门
							records.setFaceUrl(data.getRealFaceUrl());
						}else{
							records.setOpenType(OperationConstant.THREE); //远程开门
						}
						SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
						Date accessDate = null;
						try {
							accessDate = sdf.parse(data.getOpenTime());
						} catch (ParseException e) {
							e.printStackTrace();
						}
						records.setOpenTime(accessDate);
						records.setUserId(data.getUserId());
						records.setDeviceId(dbDevice.getId());
						records.setDeviceName(dbDevice.getName());
						records.setSerialNum(serialNumber);
						records.setIsOut(dbDevice.getIsOut());
						records.setTemperature(data.getTemperature());
						records.setResidentialId(dbDevice.getResidentialId());
						this.accessRecordClient.save(records);
					}
				}
			});
		}
		return R.success("success");
	}

	@Override
	@PostMapping(value = "/qinLin/recordQinLinApiLog")
	public R<String> recordQinLinApiLog(@RequestBody QinlinApiLog qinlinApiLog) {
		R<String> resultBean = this.recordQinLinApiLog(qinlinApiLog);
		return resultBean;
	}

	@Override
	@PostMapping(value = "/qinLin/addCommunity")
	public R<String> addCommunity(@RequestBody QLinCommunityDevices qLinCommunityDevices) {
		R<String> resultBean = null;
		ApiResultBean<Long> apiResultBean = null;
		try {
			apiResultBean = qinLinHttpUtil.addCommunity(qLinCommunityDevices);
			QinlinApiLog qLinApiLog = new QinlinApiLog();
			qLinApiLog.setCode(apiResultBean.getCode());
			qLinApiLog.setMessage(apiResultBean.getMessage());
			qLinApiLog.setReqData(JsonUtils.objectToJson(qLinCommunityDevices));
			qLinApiLog.setData(JsonUtils.objectToJson(apiResultBean.getData()));
			qLinApiLog.setMethod("新增小区");
			this.qinlinApiLogClient.save(qLinApiLog);
			boolean addSuccess = apiResultBean.getSuccess();
			if(addSuccess){
				Long residentialId = qLinCommunityDevices.getResidentialId();
				Residential searchEntity = new Residential();
				searchEntity.setId(residentialId);
				Residential residential = this.residentialClient.detail(searchEntity);
				residential.setThirdResidentialId(apiResultBean.getData().toString());
				this.residentialClient.update(residential);
				resultBean = R.success("添加小区成功");
			}else{
				resultBean = R.fail("添加小区失败：" + apiResultBean.getMessage());
			}
		}catch (Exception e){
			QinlinApiLog qLinApiLog = new QinlinApiLog();
			qLinApiLog.setCode(-1);
			qLinApiLog.setMessage(e.getMessage());
//            qLinApiLog.setData(JsonUtils.objectToJson(apiResultBean.getData()));
			qLinApiLog.setMethod("新增小区");
			this.qinlinApiLogClient.save(qLinApiLog);
			resultBean = R.fail("添加小区异常");
		}
		return resultBean;
	}

	@Override
	@PostMapping(value = "/qinLin/addDevices")
	public R<String> addDevices(@RequestBody QLinCommunityDevices qLinCommunityDevices) {

		R<String> resultBean = null;
		ApiResultBean apiResultBean = null;
		try {
			apiResultBean = qinLinHttpUtil.addDevices(qLinCommunityDevices);
			QinlinApiLog qLinApiLog = new QinlinApiLog();
			qLinApiLog.setCode(apiResultBean.getCode());
			qLinApiLog.setMessage(apiResultBean.getMessage());
			qLinApiLog.setReqData(JsonUtils.objectToJson(qLinCommunityDevices));
			qLinApiLog.setData(JsonUtils.objectToJson(apiResultBean.getData()));
			qLinApiLog.setMethod("新增门禁设备");
			this.qinlinApiLogClient.save(qLinApiLog);
			boolean addSuccess = apiResultBean.getSuccess();
			if(addSuccess){
				resultBean = R.success("新增门禁设备成功");
			}else{
				resultBean = R.fail("新增门禁设备失败");
			}
		}catch (Exception e){
			QinlinApiLog qLinApiLog = new QinlinApiLog();
			qLinApiLog.setCode(-1);
			qLinApiLog.setMessage(e.getMessage());
//            qLinApiLog.setData(JsonUtils.objectToJson(apiResultBean.getData()));
			qLinApiLog.setMethod("新增门禁设备");
			this.qinlinApiLogClient.save(qLinApiLog);
			resultBean = R.fail("新增门禁设备异常：" + apiResultBean.getMessage());
		}
		return resultBean;
	}


}
