package com.ruoyi.device.mqtt.handler.decoder.json.service;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.device.domain.model.TsbUserDeviceBind;
import com.ruoyi.device.mqtt.annotation.JsonCmdUpHandler;
import com.ruoyi.device.mqtt.constants.MqttConstants;
import com.ruoyi.device.mqtt.domain.BaseJsonBody;
import com.ruoyi.device.mqtt.domain.decoder.DeviceLoginRequest;
import com.ruoyi.device.mqtt.domain.encoder.DeviceLoginResponse;
import com.ruoyi.device.mqtt.enums.CmdTypeEnum;
import com.ruoyi.device.mqtt.handler.decoder.json.IJsonCmdUpHandler;
import com.ruoyi.device.mqtt.vo.CommonHeader;
import com.ruoyi.device.mqtt.vo.CommonTopic;
import com.ruoyi.device.service.ITsbUserDeviceService;
import com.ruoyi.device.mqtt.handler.DeviceOnlineManager;
import com.ruoyi.device.mqtt.vo.DeviceOnlineInfo;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.system.service.ISysUserService;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 调试宝登录：tsb:login:up → tsb:login:down
 *
 * @author lwm
 */
@JsonCmdUpHandler(cmdType = CmdTypeEnum.TSB_LOGIN)
public class DeviceLoginService implements IJsonCmdUpHandler
{
    private static final Logger log = LoggerFactory.getLogger(DeviceLoginService.class);

    @Resource
    private ITsbUserDeviceService tsbUserDeviceService;
    @Resource
    private ISysUserService userService;
    @Resource
    private SysPermissionService permissionService;
    @Resource
    private DeviceOnlineManager deviceOnlineManager;

    @Override
    public BaseJsonBody handle(CommonTopic topic, CommonHeader header, String bodyJson, CmdTypeEnum cmd)
    {
        DeviceLoginRequest request = JSON.parseObject(bodyJson, DeviceLoginRequest.class);
        if (request == null)
        {
            log.info("调试宝登录报文体解析失败");
            return BaseJsonBody.fail(topic.getDeviceType(), topic.getDeviceSn(), cmd.getCmdDownType(), "调试宝登录报文体解析失败");
        }

        // 1、用户信息校验
        String userName = request.getUserName();
        if (StringUtils.isEmpty(userName))
        {
            log.info("用户名不能为空");
            return BaseJsonBody.fail(request.getDeviceType(), request.getDeviceSn(), cmd.getCmdDownType(), "用户名不能为空");
        }
        SysUser user = userService.selectUserByUserName(userName);
        if (StringUtils.isNull(user))
        {
            log.info("登录用户:{}不存在", userName);
            return BaseJsonBody.fail(request.getDeviceType(), request.getDeviceSn(), cmd.getCmdDownType(), "当前登录用户不存在");
        }
        if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
        {
            log.info("登录用户:{}已被删除", userName);
            return BaseJsonBody.fail(request.getDeviceType(), request.getDeviceSn(), cmd.getCmdDownType(), "当前登录用户已被删除");
        }
        if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
        {
            log.info("登录用户:{}已被停用", userName);
            return BaseJsonBody.fail(request.getDeviceType(), request.getDeviceSn(), cmd.getCmdDownType(), "当前登录用户已被停用");
        }
        if (StringUtils.isEmpty(request.getUserPassword())
            || !SecurityUtils.matchesPassword(request.getUserPassword(), user.getPassword()))
        {
            log.info("登录用户：{} 密码错误，请重新输入.", userName);
            return BaseJsonBody.fail(request.getDeviceType(), request.getDeviceSn(), cmd.getCmdDownType(), "密码错误，请重新输入");
        }

        // 2、用户设备绑定关系
        TsbUserDeviceBind bindQuery = new TsbUserDeviceBind();
        bindQuery.setUserId(user.getUserId());
        bindQuery.setImei(request.getImei());
        TsbUserDeviceBind bindResult = tsbUserDeviceService.selectTsbUserDeviceBind(bindQuery);
        if (bindResult == null)
        {
            log.info("用户：{} 未绑定设备.", userName);
            return BaseJsonBody.fail(request.getDeviceType(), request.getDeviceSn(), cmd.getCmdDownType(), "当前用户未绑定设备");
        }

        // 3、返回登录结果
        DeviceLoginResponse response = new DeviceLoginResponse();
        response.setCmdType(cmd.getCmdDownType());
        response.setDeviceType(request.getDeviceType());
        response.setDeviceSn(request.getDeviceSn());
        response.setCode(MqttConstants.SUCCESS_CODE);
        response.setMsg("登录成功");
        response.setUserName(user.getUserName());
        response.setPhoneNumber(user.getPhonenumber());
        response.setNickName(user.getNickName());
        List<SysRole> roles = user.getRoles();
        if (StringUtils.isNotEmpty(roles))
        {
            String roleNames = roles.stream()
                    .map(SysRole::getRoleName)
                    .filter(StringUtils::isNotEmpty)
                    .collect(Collectors.joining(","));
            response.setRoleName(roleNames);
        }
        Set<String> permissions = permissionService.getMenuPermission(user);
        response.setPermissions(permissions);

        // 4、设备 MQTT 登录成功，注册 deviceSn 在线映射
        DeviceOnlineInfo onlineInfo = new DeviceOnlineInfo();
        onlineInfo.setUserId(user.getUserId());
        onlineInfo.setUserName(user.getUserName());
        onlineInfo.setPhoneNumber(user.getPhonenumber());
        onlineInfo.setNickName(user.getNickName());
        onlineInfo.setRoleName(response.getRoleName());
        onlineInfo.setPermissions(response.getPermissions());
        onlineInfo.setDeviceId(bindResult.getDeviceId());
        onlineInfo.setDeviceSn(request.getDeviceSn());
        onlineInfo.setDeviceType(request.getDeviceType());
        onlineInfo.setImei(request.getImei());
        deviceOnlineManager.loginOnline(onlineInfo);

        return response;
    }

}
