package io.renren.service;

import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class HikVisionService{
        private static Logger logger = LoggerFactory.getLogger(HikVisionService.class);
        static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
        static String m_sUsername = "admin";//设备用户名    可能不一样 自己问问现场
        static String m_sPassword = "admin1234";//设备密码
        static short m_sPort = 8000;//端口号，这是默认的
        public NativeLong lUserID;//用户句柄
        public NativeLong lAlarmHandle;//报警布防句柄
        public int lListenHandle;//报警监听句柄
        public NativeLong RemoteConfig;
        public static int code = 5;

    public  void initEnter(String m_sDeviceIP, int remainMinuteTime) {
        // 初始化
        Boolean flag = hCNetSDK.NET_DVR_Init();
        if (flag){
            System.out.println("初始化成功");
        }else{
            System.out.println("初始化失败");
        }
        //设置连接时间与重连时间
        hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
        hCNetSDK.NET_DVR_SetReconnect(100000, true);
        //设备信息, 输出参数
        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
        HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
        // 注册设备-登录参数，包括设备地址、登录用户、密码等
        m_strLoginInfo.sDeviceAddress = new byte[hCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
        m_strLoginInfo.sUserName = new byte[hCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
        m_strLoginInfo.sPassword = new byte[hCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
        System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
        m_strLoginInfo.wPort = m_sPort;
        m_strLoginInfo.bUseAsynLogin = false; //是否异步登录：0- 否，1- 是
        m_strLoginInfo.write();

        //设备信息, 输出参数
        int lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo,m_strDeviceInfo);
        if(lUserID< 0){
            System.out.println("hCNetSDK.NET_DVR_Login_V30()"+"\n" +hCNetSDK.NET_DVR_GetErrorMsg(null));
            hCNetSDK.NET_DVR_Cleanup();
            return;
        }


        //设置报警回调函数
        if (!hCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(this::EnterCallBack,null )){
            System.out.println("设置回调函数失败"+hCNetSDK.NET_DVR_GetLastError());
            return;
        }else {
            System.out.println("设置回调函数成功");
        }
        //启用布防
        HCNetSDK.NET_DVR_SETUPALARM_PARAM lpSetupParam = new HCNetSDK.NET_DVR_SETUPALARM_PARAM();
        lpSetupParam.dwSize = 0;
        lpSetupParam.byLevel = 1;//布防优先级：0- 一等级（高），1- 二等级（中）
        lpSetupParam.byAlarmInfoType = 1;//上传报警信息类型: 0- 老报警信息(NET_DVR_PLATE_RESULT), 1- 新报警信息(NET_ITS_PLATE_RESULT)
        int lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID,lpSetupParam);
        if (lAlarmHandle< 0)
        {
            System.out.println("NET_DVR_SetupAlarmChan_V41 error, %d\n"+hCNetSDK.NET_DVR_GetLastError());
            hCNetSDK.NET_DVR_Logout(lUserID);
            hCNetSDK.NET_DVR_Cleanup();
            return;
        }
        System.out.println("门禁进入布防成功,开始监测车辆");

        //启动监听----------------------------------------------
        int iListenPort = 8000;
        String m_sListenIP = "127.0.0.1";

        lListenHandle = hCNetSDK.NET_DVR_StartListen_V30(m_sListenIP, (short) iListenPort, this::EnterCallBack, null);
        if(lListenHandle < 0) {
//            JOptionPane.showMessageDialog(null, "启动监听失败，错误号:" +  hCNetSDK.NET_DVR_GetLastError());
        }
        else {
            System.out.println("启动监听成功");
        }

    }

    public boolean EnterCallBack(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
        System.out.println("〈－－进入回调,开始识别车牌－－〉");
        try {
            int loginId = pAlarmer.lUserID;
//            HCNetSDK.NET_DVR_BARRIERGATE_CFG cfg = new HCNetSDK.NET_DVR_BARRIERGATE_CFG();
//            cfg.byLaneNo = 1 ;
//            cfg.byBarrierGateCtrl = 1;
//            boolean t = hCNetSDK.NET_DVR_RemoteControl(loginId,3128,cfg.getPointer(),cfg.size());
//            System.out.println(t);
            String sAlarmType = new String();
            String[] newRow = new String[3];
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");

            String[] sIP = new String[2];
            switch (lCommand) {
                case 0x2800:	//交通抓拍结果上传
                    HCNetSDK.NET_DVR_PLATE_RESULT strPlateResult = new HCNetSDK.NET_DVR_PLATE_RESULT();
                    strPlateResult.write();
                    Pointer pPlateInfo = strPlateResult.getPointer();
                    pPlateInfo.write(0, pAlarmInfo.getByteArray(0, strPlateResult.size()), 0, strPlateResult.size());
                    strPlateResult.read();
                    try {
                        String srt3=new String(strPlateResult.struPlateInfo.sLicense,"GBK");
                        sAlarmType = sAlarmType + ":抓拍上传，车牌："+ srt3;
                        System.out.println("车牌号============"+srt3);
                    }
                    catch (UnsupportedEncodingException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                    newRow[0] = dateFormat.format(new Date());
                    //报警类型
                    newRow[1] = sAlarmType;
                    //报警设备IP地址
                    sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                    newRow[2] = sIP[0];
                    break;
                case 0x3050:	//交通抓拍的终端图片上传
                    HCNetSDK.NET_ITS_PLATE_RESULT strItsPlateResult = new HCNetSDK.NET_ITS_PLATE_RESULT();
                    strItsPlateResult.write();
                    Pointer pItsPlateInfo = strItsPlateResult.getPointer();
                    pItsPlateInfo.write(0, pAlarmInfo.getByteArray(0, strItsPlateResult.size()), 0, strItsPlateResult.size());
                    strItsPlateResult.read();
                    try {
                        byte byDangerousVehicles = strItsPlateResult.byDangerousVehicles;
                        String srt3=new String(strItsPlateResult.struPlateInfo.sLicense,"GBK");
                        String deviceId  = new String(strItsPlateResult.byDeviceID,"GBK");

                        Map<String,String> paramMap = new HashMap<String,String>();
                        System.out.println("获取的结果为======"+srt3);
                        if("黄".equals(srt3.substring(0, 1).trim())){
                            paramMap.put("plateNumber", srt3.substring(1, srt3.length()).trim());//车牌号
                            paramMap.put("byCountry",srt3.substring(1, 2).trim());//省份
                            paramMap.put("byColor",srt3.substring(0, 1).trim());//车牌颜色
                            paramMap.put("cameraIp",new String(pAlarmer.sDeviceIP).trim());//ip地址
                            paramMap.put("picTime",dateFormat.format(new Date()));//当前时间
                            paramMap.put("wSpeed",String.valueOf(new Random().nextInt(55-5)+5));//速度 这是假的
                            sendCarNumber(srt3.substring(1, srt3.length()).trim());
                        }
                        System.out.println(paramMap.toString());
                    }
                    catch (UnsupportedEncodingException e1) {
                        // TODO Auto-generated catch blocks
                        e1.printStackTrace();
                    }
                    break;
            }
            logger.info("车辆进入：---》" +sAlarmType +" ip:"+new String(pAlarmer.sDeviceIP).trim()+"时间:"+dateFormat.format(new Date()));
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    public void sendCarNumber(String carNum){
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost post =new HttpPost("***"); //用于接收post请求传递的车牌号的地址
        StringEntity entity = null;//解决中文乱码问题
        try {
            entity = new StringEntity(carNum, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        entity.setContentEncoding("UTF-8");
        entity.setContentType("application/json");
        post.setEntity(entity);
        try {
            HttpResponse response = client.execute(post);
            String result = EntityUtils.toString(response.getEntity(),"UTF-8");
            System.out.println(result);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}
