package jnpf.attendance.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jnpf.SocketApi;
import jnpf.attendance.annotation.Machine;
import jnpf.attendance.mapper.AttendanceUserFaceMapper;
import jnpf.attendance.mapper.AttendanceUserFingerprintMapper;
import jnpf.attendance.service.MachineStrategy;
import jnpf.base.UserInfo;
import jnpf.entity.attendance.AttendanceUserFace;
import jnpf.entity.attendance.AttendanceUserFingerprint;
import jnpf.enums.attendance.ActionEnum;
import jnpf.enums.attendance.MachineEnum;
import jnpf.permission.model.user.PartUserInfoVo;
import jnpf.util.ConstantUtil;
import jnpf.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

/**
 * 猫瞳 - 考勤策略模式
 *
 * @author yanwenfu
 * @create 2024-04-03
 */
@Slf4j
@Component(value = "machineMaoTongStrategy")
public class MachineMaoTongStrategyImpl implements MachineStrategy {

    @Autowired
    private SocketApi socketApi;

    @Resource
    private AttendanceUserFaceMapper attendanceUserFaceMapper;

    @Resource
    private AttendanceUserFingerprintMapper attendanceUserFingerprintMapper;

    @Resource
    private RedisUtil redisUtil;

    @Override
    public MachineEnum getMachine() {
        return MachineEnum.MAO_TONG;
    }

    @Machine(dealAction = ActionEnum.XIA_FA, factory = MachineEnum.MAO_TONG)
    @Override
    public void addUserToMachine(UserInfo userInfo, PartUserInfoVo user, String sn) {

        // 查询用户照片
        LambdaQueryWrapper<AttendanceUserFace> userFaceQueryWrapper = new LambdaQueryWrapper<AttendanceUserFace>()
                .eq(AttendanceUserFace::getUserId, user.getUserId())
                .eq(AttendanceUserFace::getDeleteMark, ConstantUtil.NUM_FALSE);
        AttendanceUserFace userFace = attendanceUserFaceMapper.selectOne(userFaceQueryWrapper);
        // 查询用户指纹
        LambdaQueryWrapper<AttendanceUserFingerprint> fingerprintQueryWrapper = new LambdaQueryWrapper<AttendanceUserFingerprint>()
                .eq(AttendanceUserFingerprint::getUserId, user.getUserId())
                .eq(AttendanceUserFingerprint::getDeleteMark, ConstantUtil.NUM_FALSE);
        List<AttendanceUserFingerprint> fingerprintList = attendanceUserFingerprintMapper.selectList(fingerprintQueryWrapper);
        try {
            String uuid = UUID.randomUUID().toString().replace("-", "");
            JSONObject json = new JSONObject();
            json.set("cmd", "to_device");
            json.set("from", "server");
            json.set("to", sn);
            json.set("extra", uuid);
            JSONObject json1 = new JSONObject();
            json1.set("cmd", "addUser");
            json1.set("user_id", userInfo.getTenantId() + "@" + user.getUserId());
            json1.set("name", user.getRealName());
            if (null != userFace) {
                // String base64 = changeUrlToBase64(userFace.getFaceData());
                json1.set("face_template", userFace.getFaceData() + "?imageMogr2/format/jpeg");
                // json1.set("vlface_template", userFace.getFaceData());
            }
            if (!fingerprintList.isEmpty()) {
                JSONArray jsonArray = new JSONArray();
                fingerprintList.forEach(v -> {
                    JSONObject jo = new JSONObject();
                    jo.set("id", v.getDataId());
                    jo.set("data", v.getData());
                    jo.set("name", v.getDataName());
                    jsonArray.add(jo);
                });
                json1.set("fp", jsonArray);
            }
            json1.set("id_valid", "");
            json.set("data", json1);
            String key = String.format(ConstantUtil.MACHINE_MESSAGE, sn) + user.getUserId();
            JSONObject machineJson;
            if (redisUtil.exists(key)) {
                String str = redisUtil.getString(key).toString();
                machineJson = JSONUtil.parseObj(str);
            } else {
                machineJson = new JSONObject();
            }
            machineJson.set(sn, 0);
            redisUtil.insert(key, machineJson.toString(), 60L);
            redisUtil.insert(ConstantUtil.SEND_USER_CHECK + sn + ":" + uuid, json.toString(), 45L);
            socketApi.sendMsg2Client(getMachine().getValue(), sn, json.toString());
        } catch (Exception e) {
            log.error("下发成员失败: {}", e.getMessage());
        }
    }

    @Machine(dealAction = ActionEnum.SHAN_CHU, factory = MachineEnum.MAO_TONG)
    @Override
    public void deleteUserList(UserInfo userInfo, List<String> userIds, String sn) {

        try {
            List<String> list = getUserIds(userInfo, userIds);
            JSONObject json = new JSONObject();
            json.set("cmd", "to_device");
            json.set("from", "server");
            json.set("to", sn);
            json.set("extra", list);
            JSONObject json1 = new JSONObject();
            json1.set("cmd", "delMultiUser");
            json1.set("user_ids", list);
            json.set("data", json1);
            socketApi.sendMsg2Client(getMachine().getValue(), sn, json.toString());
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    private List<String> getUserIds(UserInfo userInfo, List<String> userIds) {

        List<String> list = new ArrayList<>();
        userIds.forEach(userId -> list.add(userInfo.getTenantId() + "@" + userId));
        return list;
    }

    @Override
    public void syncMachineMember(String sn) {

        try {
            JSONObject json = new JSONObject();
            json.set("cmd", "to_device");
            json.set("from", "server");
            json.set("to", sn);
            JSONObject json1 = new JSONObject();
            json1.set("cmd", "getUserInfo");
            json1.set("value", 1);
            json.set("data", json1);
            socketApi.sendMsg2Client(getMachine().getValue(), sn, json.toString());
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }
}
