package com.zd.smartlock.utils;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zd.common.core.utils.StringUtils;
import com.zd.smartlock.domain.api.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.*;


/**
 * @Author: liujh
 * @Date: 2022/08/29/11:30
 * @Description:
 */
public class SmartlockUtil {
    private static final Logger logger = LoggerFactory.getLogger(SmartlockUtil.class);

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 服务访问地址
     */
    private final static String serviceurl = "http://192.168.249.12/info";

    /***
     * 登陆账户
     */
    private final static String userlogin = "admin";

    /***
     * 登陆密码
     */
    private final static String password = "admin123";

    /**
     * 智能锁返回成功字符描述
     */
    public final static String resultMsg = "ok";

    /**
     * //授权时长(小时)
     */
    public final static Integer authsLength=1;




    public static HttpRequest httpSendPost(String url, String json) {
        return HttpRequest.post(url)
                .header("Content-Type", "application/json")
                .body(json);
    }


    /***
     * 获取token
     * @return
     */
    public static String getToken() {
        String token = null;
        String url = serviceurl + "/login/1/gettoken?userlogin=" + userlogin + "&password=" + password;
        JSONObject json = new JSONObject();
        try {
            HttpRequest request = HttpRequest.post(url)
                    .header("Content-Type", "application/json")
                    .body(json.toString());
            HttpResponse response = request.execute();
            String resultMsg = JSON.parseObject(response.body()).get("resultMsg").toString();
            //请求是否成功
            if (SmartlockUtil.resultMsg.equals(resultMsg)) {
                token = JSON.parseObject(JSON.parseObject(response.body()).get("result").toString()).get("token").toString();
            } else {
                logger.info("智能锁获取token失败:" + resultMsg);
            }
        } catch (Exception e) {
            logger.info("获取token失败：" + e);
        }
        return token;
    }

    /**
     * 获取顶级建筑
     */
    public static SlBuild getTopBuild() {
        SlBuild slBuild = null;
        try {
            String token = SmartlockUtil.getToken();
            String url = SmartlockUtil.serviceurl + "/build/1/getbuild?buildfatherid=0&page=1&rows=10&token=" + token;
            HttpRequest request = SmartlockUtil.httpSendPost(url, "");
            HttpResponse response = request.execute();
            // System.out.println(response.body());
            String resultMsg = JSON.parseObject(response.body().toString()).get("resultMsg").toString();
            if (SmartlockUtil.resultMsg.equals(resultMsg)) {
                List<SlBuild> list = JSON.parseArray(JSON.parseObject(response.body().toString()).get("result").toString(), SlBuild.class);
                slBuild = list.get(0);
            }
        } catch (Exception e) {
            logger.error("获取顶级建筑失败：" + e);
        }
        return slBuild;
    }

    /**
     * 查询房间
     *
     * @param
     * @return
     */
    public static List<SlRoom> getRoom(SlRoom room) {
        SlBuild slBuild = null;
        String token = SmartlockUtil.getToken();
        List<SlRoom> listRoom = new ArrayList<>();
        // System.out.println(token);
        try {
            //获取楼层建筑id
            String urlLc = SmartlockUtil.serviceurl + "/build/1/getbuild?buildid=0&page=1&rows=30&token=" + token;
            HttpRequest requestLc = SmartlockUtil.httpSendPost(urlLc, "");
            HttpResponse responseLc = requestLc.execute();
            String str = responseLc.body();
            //查询失败直接返回
            String resultMsg = JSON.parseObject(str).get("resultMsg").toString();
            if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
                logger.error("获取楼层建筑id失败：" + resultMsg);
                return listRoom;
            }
            String data = JSON.parseObject(JSON.parseObject(str).get("result").toString()).get("data").toString();
            List<SlBuild> listLc = JSON.parseArray(data, SlBuild.class);
            for (SlBuild build : listLc) {
                if ("3".equals(build.getBuildtype())) {
                    slBuild = build;
                    break;
                }
            }

            //查询房间 不支持条件搜索
            String urlroom = SmartlockUtil.serviceurl + "/build/2/getroom?buildid=" + slBuild.getBuildid() + "&page=" + slBuild.getPageNumber() + "&rows=" + slBuild.getPageSize() + "&token=" + token;
            HttpRequest requestRoom = SmartlockUtil.httpSendPost(urlroom, "");
            HttpResponse response = requestRoom.execute();
            String strRoom = response.body();
            String dataRoom = JSON.parseObject(JSON.parseObject(strRoom).get("result").toString()).get("data").toString();
            listRoom = JSON.parseArray(dataRoom, SlRoom.class);
        } catch (Exception e) {
            logger.error("查询房间失败：" + e);
        }
        return listRoom;
    }

    /**
     * 查询用户集合
     *
     * @param sluser
     */
    public static List<SlUser> getUser(SlUser sluser) {
        List<SlUser> list = new ArrayList<>();
        try {
            String token = SmartlockUtil.getToken();
            //sluser.getSearch() 该查询条件支持：人员编号/人员姓名/手机号检索
            String url = SmartlockUtil.serviceurl + "/card/save/8/getcardperson?persontype=1&page=" + sluser.getPageNumber() + "&rows=" + sluser.getPageSize() + "&search=" + sluser.getSearch() + "&token=" + token;
            HttpRequest request = SmartlockUtil.httpSendPost(url, "");
            HttpResponse response = request.execute();
            //查询失败直接返回
            String resultMsg = JSON.parseObject(response.body().toString()).get("resultMsg").toString();
            if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
                logger.error("查询用户集合失败1：" + resultMsg);
                return list;
            }
            String str = response.body();
            String data = JSON.parseObject(JSON.parseObject(str).get("result").toString()).get("data").toString();
            list = JSON.parseArray(data, SlUser.class);
        } catch (Exception e) {
            logger.error("查询用户集合失败2：" + e);
        }
        return list;
    }

    /**
     * 获取房间详情
     *
     * @param roomId 房间roomid
     *               返回参数根据后期需求 扩展，
     * @return
     */
    public static SlLockOnline getRoomDetails(String roomId) {
        SlLockOnline lockOnline = new SlLockOnline();
        try {
            if (StringUtils.isEmpty(roomId)) {
                logger.error("获取房间详情失败,参数roomid为空：");
                return lockOnline;
            }
            String token = SmartlockUtil.getToken();
            String url = SmartlockUtil.serviceurl + "/lockauth/operate/1/getroominfo?roomid=" + roomId + "&token=" + token;
            HttpRequest request = SmartlockUtil.httpSendPost(url, "");
            HttpResponse response = request.execute();
            //查询失败直接返回
            String resultMsg = JSON.parseObject(response.body()).get("resultMsg").toString();
            if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
                logger.error("获取房间详情失败1：" + resultMsg);
                return lockOnline;
            }
            String str = response.body();
            //System.out.println(str);
            //在线状态
            String roomnetquality = JSON.parseObject(JSON.parseObject(str).get("result").toString()).get("roomnetquality").toString();
            //门锁编号
            String lockCode = JSON.parseObject(JSON.parseObject(str).get("result").toString()).get("roomcode2").toString();
            lockOnline.setOnLine(roomnetquality);
            lockOnline.setLockCode(lockCode);
            lockOnline.setOnLineStatus("在线".equals(roomnetquality)?1:0);
            // System.out.println("房间详情，门锁状态 roomnetquality: " + roomnetquality + " lockCode: " + lockCode);
        } catch (Exception e) {
            logger.error("获取房间详情失败2：" + e);
        }
        return lockOnline;
    }

    /***
     * 开门记录
     * @param openDoorSearch
     */
    public static List<SlOpenAndClosLog> getOpenDoorLog(SlOpenDoorSearch openDoorSearch) {
        List<SlOpenAndClosLog> list = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            String token = SmartlockUtil.getToken();

            if (StringUtils.isEmpty(openDoorSearch.getRoomid())) {
                logger.error("查询开门记录集合失败,roomid为空：" + resultMsg);
                return list;
            }
            if (StringUtils.isEmpty(openDoorSearch.getRecordtype())) {
                //0或空=所有记录，1=报警记录，2=开门记录）
                openDoorSearch.setRecordtype("2");
            }
            String sdate = sdf.format(new Date()) + " 00:00:00";
            String edate = sdf.format(new Date()) + " 23:59:59";

            //sluser.getSearch() 该查询条件支持：人员编号/人员姓名/手机号检索
            String url = SmartlockUtil.serviceurl + "/lockauth/operate/2/getlockinfo?persontype=1&page=" + openDoorSearch.getPageNumber() + "&rows=" + openDoorSearch.getPageSize() +
                    "&roomid=" + openDoorSearch.getRoomid() + "&token=" + token + "&recordtype=" + openDoorSearch.getRecordtype()
                    + "&search=" + openDoorSearch.getSearch() + "&sdate=" + sdate + "&edate=" + edate;
            HttpRequest request = SmartlockUtil.httpSendPost(url, "");
            HttpResponse response = request.execute();
            // System.out.println(response.body());
            //查询失败直接返回
            String resultMsg = JSON.parseObject(response.body()).get("resultMsg").toString();
            if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
                logger.error("查询开门记录集合失败1：" + resultMsg);
                return list;
            }
            String str = response.body();
            String data = JSON.parseObject(JSON.parseObject(str).get("result").toString()).get("data").toString();
            list = JSON.parseArray(data, SlOpenAndClosLog.class);
        } catch (Exception e) {
            logger.error("查询开门记录集合失败2：" + e);
        }
        return list;
    }

    /**
     * 获取组织信息
     *
     * @param group
     */
    public static List<SlGroup> getGroup(SlGroup group) {
        List<SlGroup> list = new ArrayList<>();
        String token = SmartlockUtil.getToken();
        try {
            String url = SmartlockUtil.serviceurl + "/group/1/getgroup?&token=" + token
                    + "&page=" + group.getPageNumber() + "&rows=" + group.getPageSize() + "&pgfatherid=0";
            HttpRequest request = SmartlockUtil.httpSendPost(url, "");
            HttpResponse response = request.execute();
            //查询失败直接返回
            String resultMsg = JSON.parseObject(response.body()).get("resultMsg").toString();
            if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
                logger.error("查询开门记录集合失败1：" + resultMsg);
                return list;
            }
            String str = response.body();
            String data = JSON.parseObject(JSON.parseObject(str).get("result").toString()).get("data").toString();
            list = JSON.parseArray(data, SlGroup.class);
        } catch (Exception e) {
            logger.error("查询组织信息失败：" + e);
        }
        return list;
    }

    /***
     * 添加人员并且办理入住
     * 返回操作状态
     */
    public static Map<String, Object> addUser(SlUser user, String roomId) {
        List<SlGroup> listgroup = getGroup(new SlGroup());
        Map<String, Object> map = new HashMap<>();
        try {
            //获取组织id
            String pgid = listgroup.get(0).getPgid();
            String token = SmartlockUtil.getToken();

            /*roomId="109";
            user.setPersoncode("C016");//学号、工号
            user.setPersonname("姓名016");//姓名
            user.setPersonsex("1");//性别 （0=女，1=男）
            user.setPersontype("1");//人员类别（1=学生，2=教职工，3=临时人员
            user.setPersonmobile("13039856924");//电话*/

            //查询人员是否存在
            Boolean flg = checkUserExis(user.getPersoncode(), "1", token);
            if (!flg) {
                //新增人员
                String url = SmartlockUtil.serviceurl + "/person/save/1/saveperson?" +
                        "personcode=" + user.getPersoncode() + "&personname=" + user.getPersonname() + "&personsex=" + user.getPersonsex() +
                        "&personmobile=" + user.getPersonmobile() + "&persontype=" + user.getPersontype() + "&pgid=" + pgid + "&token=" + token;
                HttpRequest request = SmartlockUtil.httpSendPost(url, "");
                HttpResponse response = request.execute();
                // System.out.println(response.body());
                //查询失败直接返回
                String resultMsg = JSON.parseObject(response.body().toString()).get("resultMsg").toString();
                // System.out.println(resultMsg);
                if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
                    logger.error("人员添加失败1：" + resultMsg);
                    map.put("resultMsg", resultMsg);
                    return map;
                }

                //添加授权
                map = addUserAuths(token, user.getPersoncode(), roomId);
            } else {
                //查询用户是否存在授权
                String authis = checkUserAuthExis(user.getPersoncode(), token);
                if (StringUtils.isNotEmpty(authis)) {
                    //修改授权
                    map = updateAuths(token, roomId, Integer.valueOf(authis));
                } else {
                    //添加授权
                    map = addUserAuths(token, user.getPersoncode(), roomId);
                }
            }
            //操作结果
            map.put("resultMsg", resultMsg);
        } catch (Exception e) {
            logger.error("添加人员并且办理入住异常：" + e);
        }
        return map;
    }

    /***
     * 修改用户授权
     * @param token
     * @param roomId
     * @param authid
     */
    public static Map<String, Object> updateAuths(String token, String roomId, Integer authid) {
        Map<String, Object> map = new HashMap<>();
        try {
            List<SlupdateAuths> list = new ArrayList<>();
            SlupdateAuths slupdateAuths = new SlupdateAuths();
            slupdateAuths.setAuthid(authid);
            slupdateAuths.setRctype(3);
            list.add(slupdateAuths);
            //授权开始日期
            String empsdate =sdf.format(new Date());
            //授权结束日期
            String empedate = sdf.format(getTime(authsLength));

            String pw = getRandom(6);
            String url2 = SmartlockUtil.serviceurl + "/lockauth/operate/7/updateauths?token=" + token + "&roomid=" + roomId + "&password=" + pw
                    +"&empsdate="+empsdate+"&empedate="+empedate;
            HttpRequest request2 = SmartlockUtil.httpSendPost(url2, JSONObject.toJSONString(list));
            HttpResponse response2 = request2.execute();
            String resultMsg = JSON.parseObject(response2.body()).get("resultMsg").toString();
            logger.info("用户申请修改："+response2.body());
            // System.out.println(response2.body());
            logger.info("用户密码："+pw);
            // System.out.println(pw);
            map.put("password", pw);
            map.put("resultMsg", resultMsg);
        } catch (Exception e) {
            logger.error("修改用户授权失败" + e);
            // System.out.println("修改用户授权失败:" + resultMsg);
        }
        return map;
    }

    /**
     * 添加授权
     *
     * @param token
     * @param personcode
     * @param roomId
     * @return
     */
    public static Map<String, Object> addUserAuths(String token, String personcode, String roomId) {
        Map<String, Object> map = new HashMap<>();
        try {
            //入住办理
            JSONObject json = new JSONObject();
            String pw = getRandom(6);
            List<SlPostUser> postlist = new ArrayList<>();
            SlPostUser postUser = new SlPostUser();
            postUser.setPersoncode(personcode);//学号、工号
            postUser.setIssendface("1");//是否下发人脸（1是，0否）
            postUser.setIssendfinger("1");//是否下发指纹（1是，0否）
            postUser.setIssendpass("1");//是否下发密码（1是，0否）
            postUser.setManagertype(0);//权限类型（1管理权限，0使用权限，管理权限不占用入住人数）
            postUser.setPassword(pw);//6位数字密码（不允许连续数字或连续三个及以上相同数字）
            postUser.setEmpsdate(sdf.format(new Date()));//授权开始时间
            postUser.setEmpedate(sdf.format(getTime(authsLength)));  //授权结束时间，当前时间加1小时
            postlist.add(postUser);
            //System.out.println("开始时间：" + sdf.format(new Date()) + "结束时间：" + sdf.format(getTime(1)));

            //将对象转为json
            //JSONObject jsonStr = JSON.parseObject(JSONObject.toJSONString( postlist ));
            String url2 = SmartlockUtil.serviceurl + "/lockauth/save/4/saveauths?token=" + token + "&roomid=" + roomId;
            HttpRequest request2 = SmartlockUtil.httpSendPost(url2, JSONObject.toJSONString(postlist));
            HttpResponse response2 = request2.execute();
            //System.out.println(response2.body());
            //查询失败直接返回
            if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
                logger.error("人员添加后办理入住失败1：" + resultMsg);
                map.put("resultMsg", resultMsg);
                return map;
            }
            //密码
            map.put("password", pw);
        } catch (Exception e) {

        }
        return map;
    }

    /***
     * 入住-授权
     * @param user 用户参数
     * @param roomId  房间id
     * @return
     */
    public static void AuthCheckInTest(SlUser user, String roomId) {

        List<SlGroup> listgroup = getGroup(new SlGroup());
        Map<String, Object> map = new HashMap<>();
        String token = SmartlockUtil.getToken();
        roomId = "109";

        //获取组织id
        String pgid = listgroup.get(0).getPgid();
        //roomId="109";
        user.setPersoncode("C010");//学号、工号
        user.setPersonname("姓名c10");//姓名
        user.setPersonsex("1");//性别 （0=女，1=男）
        user.setPersontype("1");//人员类别（1=学生，2=教职工，3=临时人员）

        //查询人员是否存在
        Boolean flg = checkUserExis(user.getPersoncode(), "1", token);
        if (!flg) {
            String url = SmartlockUtil.serviceurl + "/person/save/1/saveperson?" +
                    "personcode=" + user.getPersoncode() + "&personname=" + user.getPersonname() + "&personsex=" + user.getPersonsex() +
                    "&persontype=" + user.getPersontype() + "&pgid=" + pgid + "&token=" + token;
            HttpRequest request = SmartlockUtil.httpSendPost(url, "");
            HttpResponse response = request.execute();
            //System.out.println(response.body());
            //查询失败直接返回
            String resultMsg = JSON.parseObject(response.body().toString()).get("resultMsg").toString();
            //System.out.println(resultMsg);
            if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
                logger.error("人员添加失败1：" + resultMsg);
                map.put("resultMsg", resultMsg);
            }
        }


        //入住办理
        String pw = getRandom(6);
        List<SlPostUser> postlist = new ArrayList<>();
        SlPostUser postUser = new SlPostUser();
        postUser.setPersoncode("C010");//学号、工号
        postUser.setIssendface("1");//是否下发人脸（1是，0否）
        postUser.setIssendfinger("1");//是否下发指纹（1是，0否）
        postUser.setIssendpass("1");//是否下发密码（1是，0否）
        postUser.setManagertype(1);//权限类型（1管理权限，0使用权限，管理权限不占用入住人数）
        postUser.setPassword(pw);//6位数字密码（不允许连续数字或连续三个及以上相同数字）
        postUser.setRoomid(roomId);
        postUser.setEmpsdate(sdf.format(new Date()));//授权开始时间
        postUser.setEmpedate(sdf.format(getTime(1)));  //授权结束时间，当前时间加1小时
        postlist.add(postUser);

        //将对象转为json
        //JSONObject jsonStr = JSON.parseObject(JSONObject.toJSONString( postlist ));
        String url2 = SmartlockUtil.serviceurl + "/lockauth/operate/9/batchauths?token=" + token;
        HttpRequest request2 = SmartlockUtil.httpSendPost(url2, JSONObject.toJSONString(postlist));
        HttpResponse response2 = request2.execute();
        //System.out.println(response2.body());
        //查询失败直接返回
        if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
            logger.error("人员添加后办理入住失败1：" + resultMsg);
            map.put("resultMsg", resultMsg);
        }
        //密码
        map.put("password", pw);
        //操作结果
        map.put("resultMsg", resultMsg);


    }

    /***
     * 查询人员是否存在
     * @param personcode 人员编码
     * @param cardtype 1（学生卡）/2（职工卡）/3（管理卡）/6（临时卡）/7（身份证）
     */
    public static Boolean checkUserExis(String personcode, String cardtype, String token) {
        Boolean flg = false;
        //String token =  SmartlockUtil.getToken();
        String urlexis = SmartlockUtil.serviceurl + "/card/save/8/getcardperson?token=" + token + "&cardtype=" + cardtype + "&page=1&rows=20&search=" + personcode;
        HttpRequest requestexis = SmartlockUtil.httpSendPost(urlexis, "");
        HttpResponse responseexis = requestexis.execute();
        //System.out.println(responseexis.body());
        String data = JSON.parseObject(JSON.parseObject(responseexis.body()).get("result").toString()).get("data").toString();
        JSONArray array = JSON.parseArray(data);
        if (array.size() > 0) {
            flg = true;
        }
        return flg;
    }


    /***
     * 查询用户是否存在授权
     * @param personcode
     * @return
     */
    public static String checkUserAuthExis(String personcode, String token) {
        String authid = null;
        //查询用户授权信息
        //String token =  SmartlockUtil.getToken();
        String urlauth = SmartlockUtil.serviceurl + "/person/2/getpersonauth?" +
                "personcode=" + personcode + "&page=1" + "&rows=50&token=" + token;
        HttpRequest requestauth = SmartlockUtil.httpSendPost(urlauth, "");
        HttpResponse responseauth = requestauth.execute();
        //System.out.println(responseauth.body());

        String data = JSON.parseObject(JSON.parseObject(responseauth.body()).get("result").toString()).get("data").toString();
        JSONArray array = JSON.parseArray(data);
        for (int i = 0; i < array.size(); i++) {
            //System.out.println(array.get(i) + "");
            String empedate = JSON.parseObject(array.get(i).toString()).get("empedate").toString();
            String authtype = JSON.parseObject(array.get(i).toString()).get("authtype").toString();
            if ("3".equals(authtype)) {
                authid = JSON.parseObject(array.get(i).toString()).get("authid").toString();
                break;
            }
        }
        return authid;
    }

    /**
     * 当前时间加 N 小时
     *
     * @param num
     * @return
     */
    public static Date getTime(int num) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.HOUR, num);
        return cal.getTime();
    }

    /**
     * 获取6位随机数
     *
     * @param length
     * @return
     */
    public static String getRandom(int length) {
        String val = "";
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            val += String.valueOf(random.nextInt(10));
        }
        return val;
    }

    public static void main(String[] args) {
        //getTopBuild();//获取顶级建筑
        /*List<SlRoom> listRoom =  getRoom( new SlRoom());
        System.out.println(listRoom.size());
        for (SlRoom slroom:listRoom ) {
            System.out.println(slroom.getRoomid()+"== "+slroom.getRoomcode());
        }*/

        /*List<SlUser> listUser  = getUser(new SlUser());
        for (SlUser user:listUser ) {
            System.out.println(user.getPersoncode()+"== "+user.getPersonname());
        }*/

        //getRoomDetails("109");

       /* SlOpenDoorSearch  search = new SlOpenDoorSearch();
        search.setRoomid("109");
        List<SlOpenAndClosLog> list = getOpenDoorLog(search);
        for (SlOpenAndClosLog oplog:list) {
            System.out.println(oplog.getPersonname()+"=="+oplog.getUnlockingtype()+" =="+oplog.getUnlockingdate());
        }*/

        //getGroup(new SlGroup());

        //addUser(new SlUser() , "");

        // AuthCheckIn(new SlUser() , "");

         //addUser(new SlUser() , "");

        // System.out.println(checkUserExis("C008","1"));

        //String token =  SmartlockUtil.getToken();
        //updateAuths( token,"109", 32);

        //getRoomDetails("109");

        //System.out.println(getRandom(6));
    }
}
