package com.community.huiju.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.community.commom.ailiyun.AESDecode;
import com.community.commom.constant.Constant;
import com.community.commom.hk.HKOpenApi;
import com.community.commom.mode.ResponseBean;
import com.community.commom.session.UserElement;
import com.community.huiju.common.welcome.WelcomeProperties;
import com.community.huiju.dao.*;
import com.community.huiju.exception.WisdomException;
import com.community.huiju.model.*;
import com.community.huiju.service.FaceServiceI;
import com.community.huiju.service.IHKService;
import com.community.huiju.service.ImageServiceI;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service("faceServicel")
@Transactional
@Slf4j
public class FaceServicelimpl implements FaceServiceI {


    @Autowired
    private TaFaceMapper taFaceMapper;

    @Autowired
    private TaUserMapper taUserMapper;

    @Autowired
    private TaSysRoleMapper taSysRoleMapper;

    @Autowired
    private ImageServiceI imageServiceI;

    @Autowired
    private WelcomeProperties welcomeProperties;

    @Autowired
    private TaUserVerifyMapper taUserVerifyMapper;

    @Autowired
    private IHKService ihkService;

    @Autowired
    private TpEquipmentMapper tpEquipmentMapper;

    @Autowired
    private TpConfigurationMapper tpConfigurationMapper;

    @Autowired
    private TpEquipmentTreeMapper tpEquipmentTreeMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean addFace(UserElement userElement, MultipartFile uploadFile, Integer otherUserId) {
        TpEquipmentTree tpEquipmentTree = tpEquipmentTreeMapper.selectByCommunityId(userElement.getCommunityId());
        ResponseBean responseBean = new ResponseBean();
        /*审核房产是否通过*/
        TaUserVerify taUserVerify= infoExist(userElement.getUserVerifyId());
        if (null == taUserVerify) {
            responseBean.addError("房产审核未通过");
            return responseBean;
        }
        // 判断是否是迎宾系统人员
        TaUser welcomeUser = taUserMapper.selectByPrimaryKey(otherUserId);
        if (null != welcomeUser && null != welcomeProperties.getCommunityId() && null != welcomeUser.getCommunityId() && welcomeUser.getCommunityId().intValue() == welcomeProperties.getCommunityId()) {
            // 开始推送迎宾
            responseBean = addWelcomeFace(uploadFile, welcomeUser);
            return responseBean;
        }


        // 当前人脸图片url
        String faceImg = img(uploadFile);
        // 房产审核id
        Integer userVerifyId = userElement.getUserVerifyId();

        /**当otherUserId不为空时判断它是否是业主下的租客或者家属*/
        if (null != otherUserId) {
            TaUserVerify otherUserVerify = getTaFaceParentId(userElement, otherUserId);
            userVerifyId = otherUserVerify.getId();
        }
        Integer activeUser = otherUserId == null ? userElement.getId() : otherUserId;

        /**
         * 删除的时候，将所有的海康设备的关联关系删除了，需要重新下发一次
         */
        // 下发门禁
        ihkService.pushPerson(activeUser + "", taUserVerify.getId());

        TaUser user = taUserMapper.selectByPrimaryKey(activeUser);
        TaFace taFace = new TaFace();
        taFace.setFaceImg(faceImg);
        taFace.setCommunityId(user.getCommunityId());
        taFace.setTaUserVerifyId(userVerifyId);
        taFace.setCreateUser(userElement.getId());
        taFace.setUpdateUser(activeUser);
        taFace.setCreateDate(new Date());
        taFace.setUpdateDate(new Date());

        /*验证身份*/
        responseBean = addVerify(activeUser, userVerifyId, uploadFile, faceImg, taFace, tpEquipmentTree);
        return responseBean;
    }

    /**
     * 修改人脸信息
     *
     * @param userElement 登入人ID
     * @param uploadFile
     * @param otherUserId 关联家属或者租客ID
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean upDateFace(UserElement userElement, MultipartFile uploadFile, Integer otherUserId) {
        TpEquipmentTree tpEquipmentTree = tpEquipmentTreeMapper.selectByCommunityId(userElement.getCommunityId());
        ResponseBean responseBean = new ResponseBean();
        // 人脸图片地址url
        String faceImg = img(uploadFile);
        // 房产 审核id
        Integer userVerifyId = userElement.getUserVerifyId();

        Integer activeUser = otherUserId == null ? userElement.getId() : otherUserId;

        /**
         * 删除的时候，将所有的海康设备的关联关系删除了，需要重新下发一次
         */
        TaUserVerify userVerify = taUserVerifyMapper.selectByPrimaryKey(userVerifyId);
        // 下发门禁
        ihkService.pushPerson(activeUser + "", userVerifyId);

        //当前修改的id否存在
        TaFace face = taFaceMapper.getByUserVerifyId(userVerifyId);
        if (null == face) {
            responseBean.addError("您的信息不存在，请录入人脸");
            return responseBean;
        }

        face.setTaUserVerifyId(userVerifyId);
        face.setFaceImg(faceImg);
        face.setUpdateUser(userElement.getId());
        face.setUpdateDate(new Date());
        ResponseBean resps = checKout(faceImg, face, false, uploadFile, activeUser, userVerify.getCommunityId(), userVerify.getRoomNoId(), userVerify.getUnitId(), tpEquipmentTree.getAppkey(), tpEquipmentTree.getSecret(), tpEquipmentTree.getHttpServer());
        if (resps.getCode().equals("0")) {
            resps.addSuccess((Object) faceImg);
        } else {
            resps.addError(resps.getMessage());
        }
        return resps;
    }

    /**
     * 验证图片是否为人脸，推送海康
     * @param faceImg
     * @param taFace
     * @param isA
     * @param uploadFile
     * @param userId
     * @param communityId
     * @param roomNoId
     * @param unitId
     * @param appkey
     * @param secret
     * @param openapi_ip_port_http 海康服务器地址
     * @return
     */
    public ResponseBean checKout(String faceImg, TaFace taFace, boolean isA, MultipartFile uploadFile, Integer userId, Integer communityId, Integer roomNoId, Integer unitId, String  appkey, String secret, String openapi_ip_port_http) {
        ResponseBean responseBean = new ResponseBean();
        TaUser user = taUserMapper.selectByPrimaryKey(userId);
        if (user.getHkUserId() == null) {
            responseBean.addError("海康人员ID不存在，无法录入");
            log.error("本地库人员ID：{}  的海康人员ID不存在", userId);
            return responseBean;
        }
        AESDecode aesd = new AESDecode();
        String body = "{\"type\": \"0\", \"image_url\":\"" + faceImg + "\"}";
        try {
            responseBean = aesd.send(body);
            JSONObject jsonObject = JSONObject.parseObject(responseBean.getMessage());
            Integer type = (Integer) jsonObject.get("errno");
            Integer faceNum = (Integer) jsonObject.get("face_num");

            /*推送海康*/
            String data = HKOpenApi.HKpersonGroupId(uploadFile, user.getHkUserId(), user.getHkPersonNo(), user.getUserName(), user.getHkCardNo(), appkey, secret, openapi_ip_port_http);
            /*boolean isA为true进行添加，为false进行修改*/
            if (0 == type && 1 == faceNum) {
                if (null == data) {
                    throw new RuntimeException("海康人脸推送失敗！");
                }
                if (isA) {
                    taFaceMapper.insertSelective(taFace);
                } else {
                    taFaceMapper.updateByPrimaryKeySelective(taFace);
                }
                responseBean.addSuccess("操作成功");

                // 设备树
                TpEquipmentTree tpEquipmentTree = tpEquipmentTreeMapper.selectByCommunityId(communityId);
                // 所有设备
                List<TpEquipment> tpEquipments = tpEquipmentMapper.selectByCommunityIdAndUnitId(communityId, unitId, 4);
                List<Map<String, Object>> equipmentUUID = getEquipmentUUID(tpEquipments);
                StringBuilder doorUuids = new StringBuilder();
                StringBuilder deviceUuids = new StringBuilder();
                equipmentUUID.forEach(e-> {
                    doorUuids.append(e.get("doorUuid"));
                    doorUuids.append(",");
                    deviceUuids.append(e.get("deviceUuid"));
                    deviceUuids.append(",");
                });
                Map<String,Object> map = Maps.newHashMap();
                map.put("appkey", tpEquipmentTree.getAppkey());
                map.put("opUserUuid", tpEquipmentTree.getOpUserUuid());
                map.put("personIds", String.valueOf(user.getHkUserId()));
                map.put("deviceUuids", deviceUuids.substring(0, deviceUuids.lastIndexOf(",")));
                map.put("type", 1);
                map.put("openapi_ip_port_http", tpEquipmentTree.getHttpServer());
                HKOpenApi.downloadFaceAndFingerInfos(map);

                //可视对讲时 指定人员人脸权限下载
                List<Integer> userIdList = new ArrayList<>();
                userIdList.add(user.getHkUserId());
                //临时设备编号
                // TODO 根据期楼栋号，来查询出门口机

                // 单元门口机
                List<TpEquipment> visualEquipments = tpEquipmentMapper.selectByCommunityIdAndUnitId(communityId, unitId, 3);
                List<String> visualList = visualEquipments.stream()
                        .map(e-> tpConfigurationMapper.selectByPrimaryKey(e.getUuidId()).getConfigurationValue())
                        .collect(Collectors.toList());
//                List<String> visualList = new ArrayList<>();
//                visualList.add("10010100000");
                HKOpenApi.visualIntercom(tpEquipmentTree.getOpUserUuid(), 1, userIdList, visualList, tpEquipmentTree.getAppkey(), tpEquipmentTree.getSecret(), tpEquipmentTree.getHttpServer());
            } else {
                responseBean.addError("请录入正确图片");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("海康人脸推送失敗！ {}", e);
            throw new RuntimeException("海康人脸推送失敗！");
        }
        return responseBean;
    }

    /**
     * 获取设备UUID
     * @param equipmentList
     * @return
     */
    private List<Map<String,Object>> getEquipmentUUID(List<TpEquipment> equipmentList) {
        return equipmentList.stream().map(equipment -> {
            TpConfiguration tpConfiguration = tpConfigurationMapper.selectByPrimaryKey(equipment.getUuidId());
            Map<String,Object> map = Maps.newHashMap();
            map.put("doorUuid", tpConfiguration.getDooruuid());
            map.put("deviceUuid", tpConfiguration.getDeviceuuid());
            return map;
        }).collect(Collectors.toList());
    }

    /**
     * 当前登入人是否有人脸信息
     */
    @Override
    public ResponseBean getTaFaceByUserId(UserElement userElement, Integer otherUserId) {
        ResponseBean responseBean = new ResponseBean();
        Integer userVerifyId = userElement.getUserVerifyId();

        /**当otherUserId不为空时判断它是否是业主下的租客或者家属*/
        if (null != otherUserId) {
            TaUserVerify userVerify = getTaFaceParentId(userElement, otherUserId);
            userVerifyId = userVerify.getId();
        }
        TaFace face = taFaceMapper.getByUserVerifyId(userVerifyId);
        if (null != face) {
            responseBean.addSuccess(face);
            return responseBean;
        }
        responseBean.addError("当前用户暂无人脸图片");
        return responseBean;

    }

    /**
     * 判断当前用户下的人员关系（家属，租客）
     */
    public TaUserVerify getTaFaceParentId(UserElement userElement, Integer otherUserId) {
        // 根据 家属/租客 的id， 和 当前的房产信息进行查询是否有值，有值就说明是 家属/租客
        List<TaUserVerify> todUserVerify = taUserVerifyMapper.selectCommunityAndAddress(otherUserId, userElement.getCommunityId(), userElement.getPhaseId(), userElement.getBuildingId(), userElement.getUnitId(), userElement.getLevelId(), userElement.getRoomNoId(), 1);
        // 判断 家属或者租客 属不属于这个业主的下面
        if (null == todUserVerify || todUserVerify.size() == 0) {
            throw new WisdomException("您输入的家属或租户ID有误或审核未通过！");
        }
//        if (!Constant.VERIFY_STATUS.equals(todUserVerify.get(0).getVerifyStatus())) {
//            throw new WisdomException("用户房产审核未通过！");
//        }

        return todUserVerify.get(0);
    }

    /**
     * 得到当前图片
     */
    private String img(MultipartFile uploadFile) {
        String faceImg = null;
        try {
            faceImg = imageServiceI.getImageUrl(uploadFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return faceImg;
    }

    /**
     * 各种身份校验
     */
    public ResponseBean addVerify(Integer userid, Integer userVerifyId, MultipartFile uploadFile, String faceImg, TaFace taFace, TpEquipmentTree tpEquipmentTree) {
        ResponseBean response = new ResponseBean();

        TaUserVerify userVerify = taUserVerifyMapper.selectByPrimaryKey(userVerifyId);
        if (null == userVerify) {
            response.addError("当前房产审核记录不存在！");
            return response;
        }
        TaUser taUser = taUserMapper.selectByPrimaryKey(userid);

        //身份为家属租客，状态为已停用
        if (null != taUser && !Constant.EFFECTIVE_STATUS.equals(taUser.getStatus())) {
            response.addError("9996", "您的身份已停用，请联系物业");
            return response;
        }

        //查询当前用户是否有人脸记录
        TaFace face = taFaceMapper.getByUserVerifyId(userVerifyId);
        if (null == face) {
            boolean isA = true;
            if (Constant.EFFECTIVE_STATUS.equals(taUser.getStatus())) {
                ResponseBean responseBean = checKout(faceImg, taFace, isA, uploadFile, userid, userVerify.getCommunityId(), userVerify.getRoomNoId(), userVerify.getUnitId(),tpEquipmentTree.getAppkey(), tpEquipmentTree.getSecret(), tpEquipmentTree.getHttpServer());
                if (responseBean.getCode().equals("0")) {
                    responseBean.addSuccess("图片录入成功");
                } else {
                    responseBean.addError(responseBean.getMessage());
                }
                return responseBean;
            }
        }
        response.addError("您的信息已存在");
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean addWelcomeFace(MultipartFile uploadFile, TaUser user) {
        ResponseBean responseBean = new ResponseBean();

        // 开始推送 迎宾系统
        String result = "";
        try {
//            Map<String, Object> parameterMap = Maps.newHashMap();
//            parameterMap.put("userName", user.getUserName());
//            String welcomeUrl = welcomeProperties.getUrl() + "/" + user.getId();
//            OkHttpRequestUtils.doPost(welcomeUrl, Maps.newHashMap(), parameterMap, uploadFile.getOriginalFilename(), uploadFile.getBytes());

            RestTemplate restTemplate = new RestTemplate();
            String faceUrl = welcomeProperties.getUrl() + "/" + user.getId() + "?userName=" + user.getUserName();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            HttpEntity httpEntity = new HttpEntity(uploadFile.getBytes());
            result = restTemplate.exchange(faceUrl, HttpMethod.POST, httpEntity, String.class).getBody();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("推送 迎宾系统失败！", e);
            throw new WisdomException("推送 迎宾系统失败！");
        }

        JSONObject jsonObject = JSONObject.parseObject(result);
        if (!jsonObject.get("code").equals(200)) {
            String message = jsonObject.get("message").toString();
            log.error(" 推送 迎宾系统失败！ {}", message);
            throw new WisdomException(message);
        }

        // 开始存储人脸的图片到本地库
        TaFace taFace = new TaFace();
        taFace.setCommunityId(user.getCommunityId());
        taFace.setCreateDate(new Date());
        taFace.setCreateUser(user.getId());
        //taFace.setTaUserId(user.getId());
        taFace.setUpdateDate(new Date());
        taFace.setUpdateUser(user.getId());
        try {
            taFace.setFaceImg(imageServiceI.getImageUrl(uploadFile));
        } catch (IOException e) {
            e.printStackTrace();
            log.error("迎宾系统 人脸图片上传阿里云失败！", e);
        }

        taFaceMapper.insertSelective(taFace);

        responseBean.addSuccess("操作成功！");
        return responseBean;
    }

    @Override
    public ResponseBean deleteFace(UserElement userElement, Integer otherUserId,Integer verifyId) {
        ResponseBean responseBean= new ResponseBean();
        TaUserVerify taUserVerify= infoExist(userElement.getUserVerifyId());
        if (null ==taUserVerify) {
            responseBean.addError("房产审核未通过");
            return responseBean;
        }
            TaUser taUser = taUserMapper.selectByPrimaryKey(taUserVerify.getUserId());

        // 设备树
        TpEquipmentTree tpEquipmentTree = tpEquipmentTreeMapper.selectByCommunityId(taUserVerify.getCommunityId());
        // 所有设备
        List<TpEquipment> tpEquipments = tpEquipmentMapper.selectByCommunityIdAndUnitId(taUserVerify.getCommunityId(), taUserVerify.getUnitId(), 4);
        List<Map<String, Object>> equipmentUUID = getEquipmentUUID(tpEquipments);
        StringBuilder doorUuids = new StringBuilder();
        StringBuilder deviceUuids = new StringBuilder();
        equipmentUUID.forEach(e-> {
            doorUuids.append(e.get("doorUuid"));
            doorUuids.append(",");
            deviceUuids.append(e.get("deviceUuid"));
            deviceUuids.append(",");
        });


        // TODO 删除人脸，是否删除海康
        // 修改人脸(图片为null时。海康删除人脸)
//        HKOpenApi.HKpersonGroupId(null, taUser.getHkUserId(), taUser.getHkPersonNo(), taUser.getUserName(), taUser.getHkCardNo(), tpEquipmentTree.getAppkey(), tpEquipmentTree.getSecret());
        // 删除 权限
        Map<String,Object> selectUserFaceMap = Maps.newHashMap();
        selectUserFaceMap.put("personIds", taUser.getHkUserId()+"");
        selectUserFaceMap.put("opUserUuid", tpEquipmentTree.getOpUserUuid());
        selectUserFaceMap.put("appkey", tpEquipmentTree.getAppkey());
        selectUserFaceMap.put("secret", tpEquipmentTree.getSecret());
        selectUserFaceMap.put("openapi_ip_port_http", tpEquipmentTree.getHttpServer());
        // 查询人脸信息
        HKOpenApi.selectUserFace(selectUserFaceMap);

        Map<String,Object> deleteUserMap = Maps.newHashMap();
        deleteUserMap.put("personIds", taUser.getHkUserId()+"");
        deleteUserMap.put("opUserUuid", tpEquipmentTree.getOpUserUuid());
        deleteUserMap.put("doorUuids", doorUuids.substring(0, doorUuids.lastIndexOf(",")));
        deleteUserMap.put("appkey", tpEquipmentTree.getAppkey());
        deleteUserMap.put("secret", tpEquipmentTree.getSecret());
        deleteUserMap.put("openapi_ip_port_http", tpEquipmentTree.getHttpServer());
        // 删除当前人脸设备信息
        String data= HKOpenApi.deleteUser(deleteUserMap);
        JSONObject object= JSONObject.parseObject(data);

        if (object.get("errorCode").equals(1)){
            String errorMessage=  object.getString("errorMessage");
            responseBean.addError(errorMessage);
            return responseBean;
        }
        Integer activeUser = otherUserId == null ? userElement.getUserVerifyId() : otherUserId;
        taFaceMapper.deleteFace(activeUser);
        // 异动同步到设备
        Map<String,Object> appointJurisdictionMap = Maps.newHashMap();
        appointJurisdictionMap.put("appkey", tpEquipmentTree.getAppkey());
        appointJurisdictionMap.put("secret", tpEquipmentTree.getSecret());
        appointJurisdictionMap.put("opUserUuid", tpEquipmentTree.getOpUserUuid());
        appointJurisdictionMap.put("personIds", taUser.getHkUserId()+"" );
        appointJurisdictionMap.put("doorUuids", doorUuids.substring(0, doorUuids.lastIndexOf(",")));
        appointJurisdictionMap.put("operateType",3);
        appointJurisdictionMap.put("includeFinger",0);
        appointJurisdictionMap.put("openapi_ip_port_http", tpEquipmentTree.getHttpServer());

         HKOpenApi.appointJurisdiction(appointJurisdictionMap);
        // HKOpenApi.selectUserSynchronization();
        // ihkService.downloadAuthorityByDeviceUuids();
        return responseBean;

    }

    /*校验房产是否审核通过*/
    public TaUserVerify infoExist(Integer verifyID){
        /*查询当前的房产ID*/
        TaUserVerify taUserVerify = null;
      if (!"".equals(verifyID)) {
        taUserVerify = taUserVerifyMapper.selectByPrimaryKey(verifyID);
      }
      if (null!= taUserVerify && taUserVerify.getVerifyStatus().equals("1")) {
          return taUserVerify;
      }
      return  null;
    }
}


