package jnpf.attendance.controller;

import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import jnpf.attendance.service.AttenceMachineService;
import jnpf.attendance.service.AttendanceUserFaceService;
import jnpf.attendance.service.MachineStrategy;
import jnpf.attendance.service.RV1109MachineService;
import jnpf.base.UserInfo;
import jnpf.config.MqttConfiguration;
import jnpf.enums.attendance.MachineEnum;
import jnpf.model.attendance.vo.UserFaceVo;
import jnpf.permission.entity.UserEntity;
import jnpf.permission.model.user.PartUserInfoVo;
import jnpf.util.*;
import jnpf.util.attendance.MachineStrategyFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * RV1109考勤机控制器
 *
 * @author yanwenfu
 * @create 2024-04-09
 */
@RestController
@Slf4j
@RequestMapping
public class RV1109MachineController {

    @Autowired
    private CustomTenantUtil tenantUtil;

    @Autowired
    private RV1109MachineService rv1109MachineService;

    @Autowired
    private AttendanceUserFaceService attendanceUserFaceService;

    @Autowired
    private AttenceMachineService attenceMachineService;

    @Autowired
    private MqttConfiguration mqttConfiguration;

    @Autowired
    private RedisUtil redisUtil;

    @Resource
    private MachineStrategyFactory machineStrategyFactory;

    /**
     * 设备登录
     * @return java.lang.Object
     */
    @PostMapping(value = "/device/login")
    @NoDataSourceBind
    public Object deviceLogin(@RequestBody Map<String, Object> params) {

        String devSno = params.get("dev_sno").toString();
        String token = redisUtil.getHashValues(ConstantUtil.ATTENDANCE_DEVICE, devSno);
        if (StringUtils.isEmpty(token)) {
            token = UUID.randomUUID().toString();
            redisUtil.insertHash(ConstantUtil.ATTENDANCE_DEVICE, devSno, token);
        }
        JSONObject json1 = new JSONObject();
        json1.set("code", 0);
        json1.set("dev_sno", devSno);
        json1.set("msg", "登陆成功");
        json1.set("success", true);
        json1.set("token", token);
        JSONObject json2 = new JSONObject();
        String broker = mqttConfiguration.getHost();
        String[] split = broker.split(":");
        String host = split[1].substring(2);
        Integer port = Integer.parseInt(split[2]);
        json2.set("host", host);
        json2.set("keepalive", 60);
        json2.set("login", mqttConfiguration.getUsername());
        json2.set("password", mqttConfiguration.getPassword());
        json2.set("port", port);
        json2.set("qos", mqttConfiguration.getQos());
        json2.set("topic", devSno);
        json1.set("mqinfo", json2);
        return json1;
    }

    /**
     * 设备同步成员
     * @return java.lang.Object
     */
    @PostMapping(value = "/device/sync_person")
    @NoDataSourceBind
    @SuppressWarnings("unchecked")
    public Object deviceSyncPerson(@RequestBody Map<String, Object> params) {

        // 获取租户信息
        Map<String, Object> pathParamMap = (Map<String, Object>) params.get("path_params");
        JSONArray array = JSONUtil.parseArray(pathParamMap.get("person_list"));
        String userIdStr = array.get(0).toString();
        String tenantId = userIdStr.split("@")[0];
        String userId = userIdStr.split("@")[1];
        tenantUtil.checkOutTenant(tenantId, userId);
        JSONObject json = new JSONObject();
        json.set("code", 0);
        json.set("msg", "OK");
        json.set("success", true);
        json.set("person_list", getJsonArray(userId, tenantId));
        return json;
    }

    /**
     * 返回结果至设备
     * @return java.lang.Object
     */
    @PostMapping(value = "/device/notify")
    @NoDataSourceBind
    public Object deviceNotify(@RequestBody Map<String, Object> params) {

        // 获取租户信息
        boolean b = (boolean) params.get("success");
        JSONObject json = new JSONObject();
        if (b) {
            json.set("code", 0);
            json.set("msg", "OK");
            json.set("success", true);
        } else {
            json.set("code", 0);
            json.set("msg", "NOT OK");
            json.set("success", false);
        }
        return json;
    }

    private JSONArray getJsonArray(String userId, String tenantId) {

        JSONArray array = new JSONArray();
        UserEntity user = rv1109MachineService.getUserInfoById(userId, tenantId);
        if (null == user) {
            log.error("用户不存在, 用户ID：{}", userId);
            return array;
        }
        // 查询人脸
        UserFaceVo userFace = attendanceUserFaceService.getUserFace(user.getId());
        if (null == userFace) {
            log.error("人脸数据不存在, 用户ID：{}", userId);
            return array;
        }
        JSONObject json = new JSONObject();
        json.set("person_id", tenantId + "@" + user.getId());
        json.set("person_name", user.getRealName());
        json.set("person_type", "4");
        json.set("sex", null == user.getGender() ? 0 : user.getGender());
        JSONArray picArray = new JSONArray();
        picArray.add(userFace.getFaceData());
        json.set("templateImgUrl", picArray);
        json.set("qr", "");
        json.set("id_card", "");
        json.set("birthday", null == user.getBirthday() ? "" : DateDetail.getDate2Str(user.getBirthday(), DateDetail.DF));
        array.add(json);
        return array;
    }

    /**
     * 记录上传
     * @return java.lang.Object
     */
    @PostMapping(value = "/record/upload/online")
    @NoDataSourceBind
    public Object recordUploadOnline(@RequestBody Map<String, Object> params) {

        // 获取租户信息
        String personIdStr = params.get("person_id").toString();
        String tenantId = personIdStr.split("@")[0];
        String userId = personIdStr.split("@")[1];
        tenantUtil.checkOutTenant(tenantId, userId);
        // 获取设备号
        String sn = params.get("dev_sno").toString();
        // 获取对比结果
        int captureStatus = Integer.parseInt(params.get("capture_status").toString());
        if (ConstantUtil.NUM_TRUE == captureStatus) {
            // 对比通过
            String b = attenceMachineService.clockIn(sn, userId, tenantId);
            if (StringUtils.isNotEmpty(b)) {
                log.error("打卡失败");
            }
        }
        JSONObject json = new JSONObject();
        json.set("code", 0);
        json.set("msg", "OK");
        json.set("success", true);
        return json;
    }

    /**
     * 测试方法
     * @return java.lang.String
     */
    @GetMapping("/sendMqtt/{type}")
    @NoDataSourceBind
    public String sendMqtt(@PathVariable(value = "type") String type) {

        MachineEnum machineEnum = MachineEnum.getMachineEnum(MachineEnum.YU_QUE.getValue());
        MachineStrategy machineStrategy = machineStrategyFactory.getMachineStrategy(machineEnum);
        UserInfo userInfo = new UserInfo();
        userInfo.setTenantId("ftb_dev");
        PartUserInfoVo user = new PartUserInfoVo();
        user.setUserId("471608060058616325");
        String sn  = "0A:0C:E1:43:B0:37";
        if (type.equals("add")) {
            machineStrategy.addUserToMachine(userInfo, user, sn);
        }
        if (type.equals("delete")) {
            machineStrategy.deleteUserList(userInfo, Stream.of(user.getUserId()).collect(Collectors.toList()), sn);
        }
        return "发送结束";
    }
}
