package com.mortals.xhx.module.device.service.impl;

import com.alibaba.fastjson.JSON;
import com.mortals.framework.common.Rest;
import com.mortals.framework.service.impl.AbstractCRUDCacheServiceImpl;
import com.mortals.xhx.common.code.DeviceMethodEnum;
import com.mortals.xhx.common.code.DeviceStatusEnum;
import com.mortals.xhx.common.code.EnabledEnum;
import com.mortals.xhx.common.code.MeetStatusEnum;
import com.mortals.xhx.common.pdu.LoginForm;
import com.mortals.xhx.common.pdu.device.DeviceReq;
import com.mortals.xhx.feign.device.IDeviceFeign;
import com.mortals.xhx.module.device.model.DeviceQuery;
import com.mortals.xhx.module.room.model.RoomDeviceEntity;
import com.mortals.xhx.module.room.model.RoomDeviceQuery;
import com.mortals.xhx.module.room.service.RoomDeviceService;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.xhx.module.device.dao.DeviceDao;
import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.service.DeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * DeviceService
 * 设备管理 service实现
 *
 * @author zxfei
 * @date 2023-05-22
 */
@Service("deviceService")
@Slf4j
public class DeviceServiceImpl extends AbstractCRUDCacheServiceImpl<DeviceDao, DeviceEntity, Long> implements DeviceService {

    @Autowired
    private IDeviceFeign deviceFeign;
    @Value("${token.loginName:'admin'}")
    private String loginName;
    @Value("${token.password:'admin'}")
    private String password;
    @Autowired
    private RoomDeviceService roomDeviceService;

    @Override
    protected void validData(DeviceEntity entity, Context context) throws AppException {
        super.validData(entity, context);
        entity.setDeviceCode(entity.getDeviceMac());
    }

    @Override
    protected void saveBefore(DeviceEntity entity, Context context) throws AppException {
        super.saveBefore(entity, context);
    }

    @Override
    protected void saveAfter(DeviceEntity entity, Context context) throws AppException {
        super.saveAfter(entity, context);
        RoomDeviceEntity roomDeviceEntity = new RoomDeviceEntity();
        roomDeviceEntity.initAttrValue();
        roomDeviceEntity.setRoomId(entity.getRoomId());
        roomDeviceEntity.setRoomName(entity.getRoomName());
        roomDeviceEntity.setDeviceId(entity.getId());
        roomDeviceEntity.setDeviceCode(entity.getDeviceCode());
        roomDeviceEntity.setDeviceName(entity.getDeviceName());
        roomDeviceService.save(roomDeviceEntity, context);
    }

    @Override
    protected void updateBefore(DeviceEntity entity, Context context) throws AppException {
        super.updateBefore(entity, context);
        DeviceEntity beforeEntity = this.get(entity.getId(), context);

        if (!beforeEntity.getDeviceCode().equals(entity.getDeviceCode())) {
            RoomDeviceQuery roomDeviceQuery = new RoomDeviceQuery();
            roomDeviceQuery.setDeviceCode(beforeEntity.getDeviceCode());
            roomDeviceQuery.setRoomId(entity.getRoomId());
            RoomDeviceEntity roomDeviceEntity = roomDeviceService.selectOne(roomDeviceQuery);
            if (!ObjectUtils.isEmpty(roomDeviceEntity)) {
                roomDeviceEntity.setDeviceCode(entity.getDeviceCode());
                roomDeviceEntity.setDeviceId(entity.getId());
                roomDeviceEntity.setDeviceName(entity.getDeviceName());
                roomDeviceEntity.setUpdateTime(new Date());
                roomDeviceService.update(roomDeviceEntity, context);
            }
        }
    }

    @Override
    protected void updateAfter(DeviceEntity entity, Context context) throws AppException {
        super.updateAfter(entity, context);
    }

    @Override
    public void active(String deviceCode, Context context) {
        DeviceEntity deviceEntity = this.selectOne(new DeviceQuery().deviceCode(deviceCode));
        if (ObjectUtils.isEmpty(deviceEntity)) throw new AppException("当前设备不存在！");
        if (deviceEntity.getDeviceStatus() > DeviceStatusEnum.未激活.getValue())
            throw new AppException("当前设备已激活！");
        deviceEntity.setDeviceStatus(DeviceStatusEnum.离线.getValue());
        deviceEntity.setEnabled(EnabledEnum.启用.getValue());
        this.getDao().update(deviceEntity);

        String token = getToken();
        DeviceReq deviceReq = new DeviceReq();
        deviceReq.setReceiveMethod(DeviceMethodEnum.ACTIVE.getValue());
        deviceReq.setDeviceCode(deviceCode);
        Rest<String> rest = deviceFeign.deviceCall(deviceReq, token);
        log.info("激活结果：{}", JSON.toJSONString(rest));
    }

    @Override
    public void deviceEnabled(Long id, Integer enabled, Context context) {
        DeviceEntity deviceEntity = this.get(id, context);
        if (ObjectUtils.isEmpty(deviceEntity)) throw new AppException("当前设备不存在！");
        deviceEntity.setEnabled(enabled);
        deviceEntity.setUpdateTime(new Date());
        deviceEntity.setUpdateUserId(getContextUserId(context));
        this.getDao().update(deviceEntity);
        String token = getToken();
        DeviceReq deviceReq = new DeviceReq();
        deviceReq.setReceiveMethod(DeviceMethodEnum.ENABLED.getValue());
        deviceReq.setDeviceCode(deviceEntity.getDeviceCode());
        Rest<String> rest = deviceFeign.deviceCall(deviceReq, token);
        log.info("启用结果：{}", JSON.toJSONString(rest));
    }


    private String getToken() {
        LoginForm loginForm = new LoginForm();
        loginForm.setLoginName(loginName);
        loginForm.setPassword(password);
        Rest<String> rest = deviceFeign.getToken(loginForm);
        String token = rest.getData();
        return token;
    }
}