package com.sptg.repeater.dh;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.sptg.repeater.utils.DateUti;
import com.sptg.repeater.utils.HttpUti;
import com.sptg.repeater.vo.CommonValues;
import com.sptg.repeater.vo.Response;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 大豪设备执行操作
 * @author yb
 * @date 2020-04-21
 */
@Component
public class DHExecute {
    private static final Logger logger = Logger.getLogger(DHExecute.class);

    @Autowired
    private CommonValues cv;

    /**
     * 获取设备在线状态
     * @param object
     * @return
     */
    public Response checkDeviceOnLineStatus(String serialNumber, JSONObject object) {

        JSONObject data =  JSONUtil.parseObj(object.get("data"));

        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("DEVICE_ID", serialNumber);

        // 查询是否在线
        return this.postCallback("checkDeviceOnLineStatus", paramMap, object);
    }

    /**
     * 远程开门
     * @param object
     * @return
     */
    public Response openDoor(String serialNumber, JSONObject object) {
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("DEVICE_ID", serialNumber);
        paramMap.put("DEVICEPSW", object.get("adminPwd"));
        String id = (String)object.get("id");
        String userId = (String)object.get("data");
        paramMap.put("SERIALNO", id + "=" + userId);

        // 查询是否在线
        return this.postCallback("openRemoteDeviceLock", paramMap, object);
    }

    /**
     * 添加门禁卡（单张）
     * @param object
     * @return
     */
    public Response serviceAddKey(String serialNumber, String adminPwd, JSONObject object){
        JSONObject data =  JSONUtil.parseObj(object.get("data"));

        String keyID = formatCardNo(data.getStr("cardNo"));
        if(StrUtil.isBlank(keyID)){
            JSONObject errData = new JSONObject();
            errData.put("cardNo", data.getStr("cardNo"));
            HttpUti.postLzAbnormal(object, "卡号错误", errData);
            // 卡号错误
            return new Response(10000);
        }

        String sDate = data.getStr("beginDate");
        String eDate = data.getStr("endDate");

        Map<String, Object> map = DateUti.dateCompare(sDate, eDate);
        boolean isOk = Convert.toBool(map.get("isOk"));
        if(!isOk){
            JSONObject errData = new JSONObject();
            errData.put("beginDate", sDate);
            errData.put("endDate", eDate);
            HttpUti.postLzAbnormal(object, map.get("errMsg").toString(), errData);
            // 卡号使用时间错误
            return new Response(10001);
        }

        String keyStartDate = map.get("startDate").toString();
        String date = map.get("endDate").toString();

        return addKey(serialNumber, adminPwd, object, keyID, 0, keyStartDate, date, 1);
    }

    /**
     * 添加门禁卡（多张）
     * @param object
     * @return
     */
    public Response serviceAddKeyBatch(String serialNumber, String adminPwd, JSONObject object){
        JSONObject data =  JSONUtil.parseObj(object.get("data"));
        String keyID = formatCardNo(data.getStr("cardNo"));
        if(StrUtil.isBlank(keyID)){
            HttpUti.postLzAbnormal(object, "卡号错误", null);
            // 卡号错误
            return new Response(10000);
        }

        String sDate = data.getStr("beginDate");
        String eDate = data.getStr("endDate");

        Date startDate = DateUtil.parse(sDate);
        String keyStartDate = DateUtil.format(startDate, "yyyyMMddHHmmss");

        Date endDate = DateUtil.parse(eDate);
        String date = DateUtil.format(endDate, "yyyyMMddHHmmss");

        return addKey(serialNumber, adminPwd, object, keyID, 1, keyStartDate, date, 1);
    }

    public Response serviceAddKeyMore_test(String serialNumber, String adminPwd, JSONObject object){
        JSONObject data =  JSONUtil.parseObj(object.get("data"));

        // 1863041840 门禁卡号
        String keyID = "";
        String keyStartDate = "";
        String date = "";

        int keyCount = 0;

        for(int i = 10000; i < 10010; i ++){
            keyCount ++;
            keyID += formatCardNo(Convert.toStr(i));
            keyStartDate += "20200406110000";
            date += "20210406110000";
            if(i == 10005){
                keyCount ++;
                keyID += formatCardNo("1863041840");
                keyStartDate += "20200406110000";
                date += "20210406110000";
            }
        }

        return addKey(serialNumber, adminPwd, object, keyID, 1, keyStartDate, date, keyCount);
    }


    public Response addKey(String serialNumber, String adminPwd, JSONObject object, String keyID, int importFlag, String keyStartDate, String date, int keyCount) {
        JSONObject data =  JSONUtil.parseObj(object.get("data"));
        String id = Convert.toStr(object.get("id"));
//        String serialNumber = data.getStr("serialNumber");
//        String adminPsw = data.getStr("adminPsw");

        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("DEVICE_ID", serialNumber);   // 设备ID
        paramMap.put("DEVICEPSW", adminPwd);      // 设备密码
        paramMap.put("KEYTYPE", 3);                // 钥匙类型（1:APP; 2:密码; 3:卡片; 4:指纹 5:身份证）
        paramMap.put("KEYCOUNT", keyCount);        // 钥匙个数
        paramMap.put("KEYID", keyID);              // 钥匙ID（如果多个则往后拼凑追加，如两个钥匙：4588B1F74588B1F8）
        paramMap.put("KEYSTARTDATE", keyStartDate);// 卡片生效时间（如果多个则往后拼凑追加，如两个钥匙的有效期：2018082910101020180829101010）
        paramMap.put("DATE", date);                // 卡片失效时间（如果多个则往后拼凑追加，如两个钥匙的有效期：2018082910101020180829101010）
        paramMap.put("SERIALNO", id);        // 接口关联值（对应回调中的SERIALNO，只在IMPORTFLAG=1时有效）
        paramMap.put("IMPORTFLAG", importFlag);    // 导入标志（非必填项，0：直接发卡 1：框架导入卡片，采用POST方式请求，如果导入卡片多余1000张，建议连续提交多次，导入前需判断设备是否在线）

        // 添加门禁卡
        return this.postCallback("serviceAddKey", paramMap, object);
    }

    /**
     * 批量发卡
     * @param serialNumber
     * @param adminPwd
     * @param object
     * @param keyID
     * @param importFlag
     * @param keyStartDate
     * @param date
     * @param keyCount
     * @return
     */
    public Response addMoreKey(String serialNumber, String adminPwd, JSONObject object, String serialNo, String keyID, int importFlag, String keyStartDate, String date, int keyCount) {
//        JSONObject data =  JSONUtil.parseObj(object.get("data"));
//        String id = Convert.toStr(object.get("id"));
//        String serialNumber = data.getStr("serialNumber");
//        String adminPsw = data.getStr("adminPsw");

        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("DEVICE_ID", serialNumber);   // 设备ID
        paramMap.put("DEVICEPSW", adminPwd);      // 设备密码
        paramMap.put("KEYTYPE", 3);                // 钥匙类型（1:APP; 2:密码; 3:卡片; 4:指纹 5:身份证）
        paramMap.put("KEYCOUNT", keyCount);        // 钥匙个数
        paramMap.put("KEYID", keyID);              // 钥匙ID（如果多个则往后拼凑追加，如两个钥匙：4588B1F74588B1F8）
        paramMap.put("KEYSTARTDATE", keyStartDate);// 卡片生效时间（如果多个则往后拼凑追加，如两个钥匙的有效期：2018082910101020180829101010）
        paramMap.put("DATE", date);                // 卡片失效时间（如果多个则往后拼凑追加，如两个钥匙的有效期：2018082910101020180829101010）
        paramMap.put("SERIALNO", serialNo);        // 接口关联值（对应回调中的SERIALNO，只在IMPORTFLAG=1时有效）
        paramMap.put("IMPORTFLAG", importFlag);    // 导入标志（非必填项，0：直接发卡 1：框架导入卡片，采用POST方式请求，如果导入卡片多余1000张，建议连续提交多次，导入前需判断设备是否在线）

        // 添加门禁卡
        return this.cardMorePostCallback("serviceAddKey", paramMap);
    }

    /**
     * 调用大豪api，发送结果到常运智慧项目
     * @param methodName 大豪api方法名称
     * @param paramMap   传递到大豪api的参数
     * @param object     常运智慧项目传递的mq信息
     * @return
     */
    public Response postCallback(String methodName, HashMap<String, Object> paramMap, JSONObject object) {

        Response res = HttpUti.postDH(cv.getDhUrl() + methodName, paramMap);

        // 执行不成功
        if (res.getErrno() != 0) {
            String errorMsg = res.getMsg();
            JSONObject resData = (JSONObject) res.getData();
            HttpUti.postLzAbnormal(object, errorMsg, resData);
        }else{
//            JSONObject jsonObject = null;
//            boolean isJsonObj = JSONUtil.isJsonObj((String) object.get("data"));
//            if(isJsonObj){
//                jsonObject = JSONUtil.parseObj(object.get("data"));
//            }else{
//                jsonObject.put("data", object.get("data"));
//            }
//            String id = Convert.toStr(object.get("id"));
//            String status = "2";
//            String errorMsg = "ok";
//            String code = object.getStr("code");
//            HttpUti.postCallback(id, code, status, errorMsg, null);
        }
        return res;
    }

    /**
     * 调用大豪api，发送结果到常运智慧项目
     * @param methodName 大豪api方法名称
     * @param paramMap   传递到大豪api的参数
     * @return
     */
    public Response cardMorePostCallback(String methodName, HashMap<String, Object> paramMap) {
        // 调用大豪api
        logger.info("dahao param ------->" + paramMap + "<----------");
        Response res = HttpUti.postDH(cv.getDhUrl() + methodName, paramMap);
        return res;
    }

    /**
     * 格式化卡号，大豪设备
     * @return
     */
    public static String formatCardNo(String cardNo){
        try {
            // 转换为16进制
//            cardNo = Integer.toHexString(Convert.toInt(cardNo));
            cardNo = Integer.toHexString(Convert.toInt(Long.parseLong(cardNo)));
            // 卡号位数长度
            int len = cardNo.length();
            // 大豪设备卡号需要的位数长度
            int maxLen = 8;
            // 卡号位数长度不足8位，前面补0
            if(len < maxLen){
                // 计算需要补几个0
                int y = maxLen - len;
                // 补0
                String bw = String.format("%0" + y + "d", 0);
                // 补到卡号前面
                cardNo = bw + cardNo;
            }
            return cardNo;
        }catch (Exception e){
            logger.error("格式化卡（大豪设备）异常：", e);
            return null;
        }
    }

    public Response delOpenDoorCard(String serialNumber, String adminPwd, JSONObject object) {
        JSONObject data =  JSONUtil.parseObj(object.get("data"));
        String serialNo = Convert.toStr(object.get("id"));
        String keyID = formatCardNo(data.getStr("cardNo"));
        if(StrUtil.isBlank(keyID)){
            JSONObject errData = new JSONObject();
            errData.put("cardNo", data.getStr("cardNo"));
            HttpUti.postLzAbnormal(object, "卡号错误", errData);
            // 卡号错误
            return new Response(10000);
        }

        HashMap<String, Object> paramMap = new HashMap<>();
//        paramMap.put("DEVICE_ID", data.get("serialNumber"));
        paramMap.put("DEVICE_ID", serialNumber);
//        paramMap.put("DEVICEPSW", data.get("adminPwd"));
        paramMap.put("DEVICEPSW", adminPwd);
        paramMap.put("KEYTYPE", 3);   // 钥匙类型 1:APP; 2:密码; 3:卡片; 4:指纹 5:身份证
        paramMap.put("KEYID", keyID); // 钥匙ID（每次只能删除一个卡片，如果删除所有卡片的话，填写: 00000000）
        paramMap.put("SERIALNO", serialNo); //流水号

        // 查询是否在线
        return this.postCallback("serviceDeleteKey", paramMap, object);
    }
}
