package com.community.huiju.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.community.commom.constant.Constant;
import com.community.commom.mode.ResponseBean;
import com.community.commom.session.UserElement;
import com.community.commom.utils.AccountValidatorUtil;
import com.community.commom.utils.BeanTools;
import com.community.commom.utils.MD5Utils;
import com.community.commom.uuid.IdGen;
import com.community.huiju.common.code.ICode;
import com.community.huiju.common.code.cache.AppkeyCache;
import com.community.commom.hk.HKConstant;
import com.community.commom.hk.HKOpenApi;
import com.community.huiju.common.messagePush;
import com.community.huiju.common.perproties.DaSuProperties;
import com.community.huiju.common.perproties.LoginCodePerproties;
import com.community.huiju.common.sign.DaSuSign;
import com.community.huiju.common.welcome.OkHttpRequestUtils;
import com.community.huiju.common.welcome.WelcomeProperties;
import com.community.huiju.dao.*;
import com.community.huiju.enums.UserVerifyEnum;
import com.community.huiju.exception.WisdomException;
import com.community.huiju.model.*;
import com.community.huiju.service.IHKService;
import com.community.huiju.service.ITaUserService;
import com.community.huiju.service.ImageServiceI;
import com.community.huiju.vo.TaUserVO;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.logging.SimpleFormatter;
import java.util.stream.Collectors;

import static com.community.commom.constant.Constant.OWNER;

/**
 * 用户业务 实现
 *
 * @author weiximei
 */
@Service("iTaUserService")
@Slf4j
public class TaUserServiceImpl implements ITaUserService {

    private IdGen idGen = IdGen.get();

    @Autowired
    private WelcomeProperties welcomeProperties;

    @Autowired
    private TaUserMapper taUserMapper;

    @Autowired
    private TaSysRoleMapper taSysRoleMapper;

    @Autowired
    private TaSysUserRoleMapper taSysUserRoleMapper;

    @Autowired
    private ToCommunitiesMapper toCommunitiesMapper;

    @Autowired
    private SysNationMapper sysNationMapper;

    @Autowired
    private TaFaceMapper taFaceMapper;

    @Autowired
    private TpBillInvoiceMapper tpBillInvoiceMapper;

    @Autowired
    private ImageServiceI imageService;

    @Autowired
    @Qualifier("phoneCodeImpl")
    private ICode iCode;

    @Autowired
    private TaUserVerifyMapper taUserVerifyMapper;

    @Autowired
    private LoginCodePerproties loginCodePerproties;

    @Autowired
    private IHKService ihkService;

    @Autowired
    private DaSuProperties daSuProperties;


    @Autowired
    private TpConfigurationMapper tpConfigurationMapper;

    @Autowired
    private TpEquipmentMapper tpEquipmentMapper;

    @Autowired
    private TpEquipmentTreeMapper tpEquipmentTreeMapper;

    /**
     * 期
     */
    @Autowired
    private TpPhaseMapper tpPhaseMapper;

    /**
     * 单元
     */
    @Autowired
    private TpUnitMapper tpUnitMapper;

    /**
     * 楼层
     */
    @Autowired
    private TpLevelMapper tpLevelMapper;

    /**
     * 栋
     */
    @Autowired
    private TpBuildingMapper tpBuildingMapper;

    /**
     * 楼栋资料库
     */
    @Autowired
    private TpBuildingOwnerInfoMapper tpBuildingOwnerInfoMapper;

    /**
     * 户号
     */
    @Autowired
    private TpRoomNoMapper tpRoomNoMapper;

    @Autowired
    private TpMessageMapper tpMessageMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean login(String loginName, String code, HttpSession session) {
        ResponseBean response = new ResponseBean();

        // 校验手机号和验证码
        iCode.checkPhoneAndCode(loginName, code);

        TaUser currentUser = hasUserPhone(loginName);
        if (null == currentUser) {
            response.addError("未注册，请先注册", loginCodePerproties.getLoginCode().get(UserVerifyEnum.NO_UNREGISTERED.getCode()) + "&phone=" + loginName + "&code=" + code);
            return response;
        }

        // 检验登录房产
        checkLogin(response, currentUser, session);

        return response;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseBean register(String parameter) {
        ResponseBean<TaUser> response = new ResponseBean();

        JSONObject jsonObject = JSONObject.parseObject(parameter);
        TaUser user = jsonObject.toJavaObject(TaUser.class);

        Map<String, Object> map = Maps.newHashMap();
        map.put("loginName", user.getLoginName());
        TaUser currentUser = taUserMapper.selectByLoginName(map);
        if (null != currentUser) {
            response.addError("手机号已被注册");
            return response;
        }

        String code = jsonObject.getString("code");
        if (StringUtils.isNotBlank(code)) {
            // 校验手机号 和验证码
            iCode.checkPhoneAndCode(user.getLoginName(), code);
        }

        // 开始注册
        user.setCreateDate(new Date());
        user.setUpdateDate(new Date());
        user.setStatus("1");
        user.setAcceptAgreementStatus("1");
        user.setUserName(user.getLoginName());
        String userName = jsonObject.getString("userName");
        if (org.apache.commons.lang3.StringUtils.isNotBlank(userName)) {
            user.setUserName(userName);
        }
        user.setRemark("这是系统自动注册!");
        user.setVerifyStatus("0");
        user.setFaceStatus("0");
        taUserMapper.insertSelective(user);

        user.setCreateUser(user.getId());
        user.setUpdateUser(user.getId());

        // 更新
        taUserMapper.updateByPrimaryKeySelective(user);
        response.addSuccess(user);
        return response;
    }

    /**
     * 检验登录房产
     *
     * @param response
     * @param currentUser
     * @return
     */
    @Override
    public ResponseBean checkLogin(ResponseBean response, TaUser currentUser, HttpSession session) {
        // 校验用户
        checkBlacklistStatusUser(currentUser);

        TaUserVO taUserVO = new TaUserVO();
        BeanUtils.copyProperties(currentUser, taUserVO);

        // 默认未绑定微信
        taUserVO.setBindingWX(Constant.NO_BINDING_WX);

        // 如果存在值，则已绑定微信
        if (StringUtils.isNotBlank(currentUser.getOpenid())) {
            taUserVO.setBindingWX(Constant.BINDING_WX);
        }

        String token = null;
        if (null != session) {
            token = session.getId();
        }

        // 校验房产
        List<TaUserVerify> taUserVerifies = taUserVerifyMapper.selectByUserId(currentUser.getId());
        taUserVerifies.forEach(e->{
            e.setVerifyUrl(loginCodePerproties.getLoginCode().get("-1") + e.getId());
        });
        taUserVO.setUserVerifyList(taUserVerifies);
        // 无关联房产
        if (null == taUserVerifies || taUserVerifies.size() == 0) {
            response.addError(UserVerifyEnum.NO_AUDIT_REAL_ESTATE.getMsg(), taUserVO, loginCodePerproties.getLoginCode().get(UserVerifyEnum.NO_AUDIT_REAL_ESTATE.getCode()) + "&token=" + token);
            return response;
        }

        // 关联一个审核通过的房产/关联一个待审核房产/关联一个审核未通过房产
        if (taUserVerifies.size() == 1) {
            TaUserVerify userVerify = taUserVerifies.get(0);

            /**
             * 这个 审核id 很重要，后面的角色，都是根据这个 审核id 查询的，
             * 登陆成功后这个 审核id 会存 session
             */
            ResponseBean responseBean = checkHouse(response, taUserVO, userVerify);
            if (!"0".equals(responseBean.getCode())) {
                responseBean.setUrl(responseBean.getUrl() + "&token=" + token);
            }
            return responseBean;
        } else if (taUserVerifies.size() >= 2) {
            response.addSuccess(UserVerifyEnum.A_MULTIPLE_REAL_ESTATE.getMsg(), taUserVO, loginCodePerproties.getLoginCode().get(UserVerifyEnum.A_MULTIPLE_REAL_ESTATE.getCode())  + "&token=" + token);
            return response;
        }

        return response;
    }

    /**
     * 设置 TaUserVO 的一些信息
     * <p>
     * 小区，省市区
     *
     * @param communityId
     * @param userVO
     */
    private void setUserVoProperties(Integer communityId, TaUserVO userVO) {
        // 获取小区
        ToCommunities toCommunities = toCommunitiesMapper.selectByPrimaryKey(communityId);
        // 省
        SysNation province = sysNationMapper.selectByPrimaryKey(toCommunities.getProvinceId());
        // 市
        SysNation city = sysNationMapper.selectByPrimaryKey(toCommunities.getCityId());
        // 区
        SysNation district = sysNationMapper.selectByPrimaryKey(toCommunities.getDistrictId());

        userVO.setAddressProvince(province.getProvince() + "" + city.getCity() + "" + district.getDistrict() + toCommunities.getCommunityName());
        userVO.setCommunityId(communityId);
        userVO.setCommunityName(toCommunities.getCommunityName());
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseBean updateLoginName(UserElement userElement, String paramets) {
        ResponseBean response = new ResponseBean();

        JSONObject jsonObject = JSONObject.parseObject(paramets);
        String phone = (String) jsonObject.get("phone");
        String code = (String) jsonObject.get("code");

        TaUser user = taUserMapper.selectByPrimaryKey(userElement.getId());

        // 校验手机号和验证码
        iCode.checkPhoneAndCode(phone, code);

        //当前小区下的电话校验
        TaUser loginName = taUserMapper.getByLoginName(user.getCommunityId(), phone);
        if (null != loginName) {
            response.addError("号码已占用");
            return response;
        }
        TpEquipmentTree tpEquipmentTree = tpEquipmentTreeMapper.selectByCommunityId(userElement.getCommunityId());
        String data = HKOpenApi.HKpersonPhone(user.getHkUserId(), user.getHkPersonNo(), user.getUserName(), phone, tpEquipmentTree.getHttpServer());
        JSONObject jsonobject = JSONObject.parseObject(data);
        int errorCode = jsonobject.getInteger("errorCode");
        if (errorCode != 0) {
            response.addError("海康电话已存在,推送海康电话修改失败");
            return response;
        }

        // 修改号码
        TaUser taUser = new TaUser();
        taUser.setLoginName(phone);
        taUser.setId(user.getId());
        taUser.setUpdateDate(new Date());
        taUser.setUpdateUser(user.getId());
        taUserMapper.updateLongName(taUser);
        response.addSuccess("修改成功");

        /**
         * 如果是 家属或者租客,修改手机号, 就不允许修改资料库的信息
         * 根据房产判断 当前是否是 业主
         */

        TaUserVerify userVerify = taUserVerifyMapper.selectByPrimaryKey(userElement.getUserVerifyId());
        TaSysRole sysRole = taSysRoleMapper.selectByPrimaryKey(userVerify.getRoleId());

        // 修改楼栋信息资料库的手机号
        // 1 业主 2 租客 3 家属
        // 只允许业主修改
        if (null != sysRole && sysRole.getId().intValue() == 1) {
            TpBuildingOwnerInfo buildingOwnerInfo = tpBuildingOwnerInfoMapper.selectByPrimaryKey(userVerify.getRoomNoId());
            buildingOwnerInfo.setOwnerTel(phone);
            tpBuildingOwnerInfoMapper.updateByPrimaryKeySelective(buildingOwnerInfo);
        }

        // 给前端返回一个空数组
        response.addSuccess(new String[0]);
        return response;
    }

    public ResponseBean getTaFaceParentId(Integer userId, Integer otherUserId) {
        ResponseBean responseBean = new ResponseBean();
        TaUser users = taUserMapper.selectByPrimaryKey(otherUserId);
        if (null == users || !userId.equals(users.getParentId())) {
            responseBean.addError("您输入的家属或租户ID有误");
            return responseBean;
        }
        return responseBean;
    }

    @Override
    public ResponseBean getAllRoomUserList(UserElement userElement) {
        ResponseBean responseBean = new ResponseBean();

        // 1.查询出当前用户的，期、楼栋、单元、楼层、户号
        // 2. 根据 期、楼栋、单元、楼层、户号、小区id，查询 审核表 得到审核记录

        TaUserVerify userVerify = taUserVerifyMapper.selectByPrimaryKey(userElement.getUserVerifyId());
        List<TaUser> userList = taUserMapper.selectHouseUserList(userElement.getCommunityId(), userVerify.getPhaseId(), userVerify.getBuildingId(), userVerify.getUnitId(), userVerify.getLevelId(), userVerify.getRoomNoId(), userElement.getId());

        responseBean.addSuccess(userList);
        return responseBean;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseBean modifyUser(UserElement userElement, String parameter) {

        ResponseBean response = new ResponseBean();

        // 前台提交的数据
        TaUser user = JSONObject.parseObject(parameter, TaUser.class);
        // 数据库数据
        TaUser taUser = taUserMapper.selectByPrimaryKey(userElement.getId());

        /**
         * 判断是否 是业主，如果业主就连着 楼栋资料库 信息修改
         */

        TaUserVerify userVerify = taUserVerifyMapper.selectByPrimaryKey(userElement.getUserVerifyId());
        TaSysRole sysRole = taSysRoleMapper.selectByPrimaryKey(userVerify.getRoleId());

        BeanTools.copyProperties(user, taUser);
        int result = taUserMapper.updateByPrimaryKeySelective(taUser);
        // int VerifyStatus= Integer.parseInt(taUser.getVerifyStatus());
        if (1 == sysRole.getId()) {
            TpBuildingOwnerInfo tpBuildingOwnerInfo = new TpBuildingOwnerInfo();
            tpBuildingOwnerInfo.setOwnerName(user.getUserName());
            tpBuildingOwnerInfo.setGender(user.getGender());
            tpBuildingOwnerInfo.setOwnerTel(user.getLoginName());
            tpBuildingOwnerInfo.setUpdateDate(new Date());
            tpBuildingOwnerInfo.setUpdateUser(taUser.getId());
            tpBuildingOwnerInfo.setId(userElement.getRoomNoId());
            tpBuildingOwnerInfoMapper.updateByPrimaryKeySelective(tpBuildingOwnerInfo);
        }
        if (result > 0) {
            response.addSuccess("修改成功!");
        } else {
            response.addError("修改失败!");
        }

        return response;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseBean startOrEndUsingUser(Integer currentUserId, Integer userId, Integer type) {
        ResponseBean response = null;
        if (Constant.EFFECTIVE.equals(type + "")) {
            response = startAndEnd(currentUserId, userId, true);
        } else {
            response = startAndEnd(currentUserId, userId, false);
        }
        return response;
    }

    /**
     * 用户停用和启用
     *
     * @param currentUserId 当前用户(业主)
     * @param userId        租客或者家属
     * @param bool          启用为 true  停用为 false
     * @return
     */
    private ResponseBean startAndEnd(Integer currentUserId, Integer userId, boolean bool) {

        // TODO 更新人字段需要待定
        /**
         * 更新人 是业主 还是 物业
         */

        ResponseBean response = new ResponseBean();

        TaUser user = taUserMapper.selectByPrimaryKey(userId);
        if (null == user) {
            response.addError("该用户不存在!");
            return response;
        }
        if (!currentUserId.equals(user.getParentId())) {
            response.addError("该用户不是您的家属或租客!");
            return response;
        }
        if (bool) {
            if (Constant.EFFECTIVE.equals(user.getStatus())) {
                response.addError("用户已启用!");
                return response;
            }
            user.setStatus(Constant.EFFECTIVE + "");
        } else {
            if (Constant.INVALID.equals(user.getStatus())) {
                response.addError("用户已停用!");
                return response;
            }
            user.setStatus(Constant.INVALID + "");
        }

        int result = taUserMapper.updateByPrimaryKeySelective(user);
        if (result > 0) {
            response.addSuccess(bool == true ? "用户启用成功!" : "用户停用成功!");
        } else {
            response.addError(bool == true ? "用户启用失败!" : "用户停用失败!");
        }

        return response;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseBean addTenantsOrDependents(UserElement userElement, String parameter) {
        ResponseBean response = new ResponseBean();

        JSONObject jsonObject = JSONObject.parseObject(parameter);
        String roleName = jsonObject.getString("roleName");

        TaUser user = jsonObject.toJavaObject(TaUser.class);
        // 调用注册接口
        response = register(parameter);
        // 返回值 code 为 1，表示已经注册
        if ("1".equals(response.getCode())) {
            // 用户数据查询出来
            Map<String, Object> map = Maps.newHashMap();
            map.put("loginName", user.getLoginName());
            user = taUserMapper.selectByLoginName(map);
        } else {
            user = (TaUser) response.getData();
        }

        // 查询角色
        TaSysRole sysRole = taSysRoleMapper.selectByRoleName(roleName);
        // 查询出当前 业主的楼栋信息
        TaUserVerify userElementUserVerify = taUserVerifyMapper.selectByPrimaryKey(userElement.getUserVerifyId());

        // 校验该用户是否已经提交了一个当前房产的审核, 包含 待审核和已审核通过
        List<TaUserVerify> userVerifyList = taUserVerifyMapper.selectCommunityAndAddressAndNotVerifyStatus2(user.getId(), userElement.getCommunityId(),
                userElement.getPhaseId(), userElement.getBuildingId(), userElement.getUnitId(),
                userElement.getLevelId(), userElement.getRoomNoId());
        if (null != userVerifyList && userVerifyList.size() > 0) {
            response.addError("您已提交了这个房产的审核！请等待户主或者物业审核后，在进行下一步操作！");
            return response;
        }

        // 开始存入审核表
        TaUserVerify userVerify = new TaUserVerify();
        userVerify.setCommunityId(userElement.getCommunityId());
        userVerify.setRoleId(sysRole.getId());
        userVerify.setUserId(user.getId());
        userVerify.setPhaseId(userElementUserVerify.getPhaseId());
        userVerify.setPhaseName(userElementUserVerify.getPhaseName());
        userVerify.setBuildingId(userElementUserVerify.getBuildingId());
        userVerify.setBuildingName(userElementUserVerify.getBuildingName());
        userVerify.setUnitId(userElementUserVerify.getUnitId());
        userVerify.setUnitName(userElementUserVerify.getUnitName());
        userVerify.setLevelId(userElementUserVerify.getLevelId());
        userVerify.setLevelName(userElementUserVerify.getLevelName());
        userVerify.setRoomNoId(userElementUserVerify.getRoomNoId());
        userVerify.setRoomNoName(userElementUserVerify.getRoomNoName());
        userVerify.setVerifyStatus("1");
        userVerify.setCreateDate(new Date());

        taUserVerifyMapper.insertSelective(userVerify);

        // 插入楼栋资料库
        TpBuildingOwnerInfo buildingInfo = getBuildingInfo(userElement, user.getLoginName());
        if (null == buildingInfo) {
            insertTpBuildingOwnerInfo(userElement, user, null, userVerify);
        }

        // 推送海康
        response = ihkService.pushPerson(user.getId()+"", userVerify.getId());
        if ("1".equals(response.getCode())) {
            throw new WisdomException("推送HK失败！");
        }
        // 推送消息
        String[] messageArr= new messagePush().messagePushAll( );
        for (String count : messageArr) {
            TpMessage message = new TpMessage();
            message.setCommunityId(userVerify.getCommunityId());
            message.setMessageType("9");
            message.setAdviceType("1");
            message.setModelType("1");
            message.setUuid(userVerify.getId());
            message.setUuidType("1");
            message.setSource("1");
            message.setMessageContent(count);
            message.setStatus("1");
            message.setResult("");
            message.setMeaasgeTypeId("");
            message.setReadStatus("0");
            message.setCreateUser(userElement.getId());
            message.setCreateDate(new Date());
            tpMessageMapper.insert(message);
        }

        response.addSuccess(user);
        return response;
    }

    /**
     * 查询 楼栋信息
     *      根据小区Id, 栋,单元,楼层,房号, 手机号
     * @param userElement
     * @param phone
     * @return
     */
    private TpBuildingOwnerInfo getBuildingInfo(UserElement userElement, String phone) {

        TpBuildingOwnerInfo selectBuild = tpBuildingOwnerInfoMapper.selectCommunityAndAddressAndPhone(userElement.getCommunityId(),
                userElement.getPhaseId(), userElement.getBuildingId(), userElement.getUnitId(), userElement.getLevelId(),
                userElement.getRoomNoId(), phone);

        return selectBuild;
    }

    /**
     * 插入 楼栋资料库
     *
     * @param userElement
     * @param user
     * @param userId 创建人
     */
    private TpBuildingOwnerInfo insertTpBuildingOwnerInfo (UserElement userElement, TaUser user, Integer userId, TaUserVerify taUserVerify) {
        TpBuildingOwnerInfo tpBuildingOwnerInfo = new TpBuildingOwnerInfo();
        // 查询 期/楼栋/单元/层/户号
        TpPhase phase = tpPhaseMapper.selectByPrimaryKey(userElement.getPhaseId());
        TpBuilding building = tpBuildingMapper.selectByPrimaryKey(userElement.getBuildingId());
        TpUnit unit = tpUnitMapper.selectByPrimaryKey(userElement.getUnitId());
        TpLevel level = tpLevelMapper.selectByPrimaryKey(userElement.getLevelId());
        TpRoomNo roomNo = tpRoomNoMapper.selectByPrimaryKey(userElement.getRoomNoId());


        // 主键是自增的, 所以设置为 null
        tpBuildingOwnerInfo.setId(null);
        tpBuildingOwnerInfo.setPhaseId(phase.getId());
        tpBuildingOwnerInfo.setPhaseName(phase.getName());
        tpBuildingOwnerInfo.setBuildingId(building.getId());
        tpBuildingOwnerInfo.setBuildingName(building.getName());
        tpBuildingOwnerInfo.setUnitId(unit.getId());
        tpBuildingOwnerInfo.setUnitName(unit.getName());
        tpBuildingOwnerInfo.setLevelId(level.getId());
        tpBuildingOwnerInfo.setLevelName(level.getName());
        tpBuildingOwnerInfo.setRoomNoId(roomNo.getId());
        tpBuildingOwnerInfo.setRoomNoName(roomNo.getName());
        tpBuildingOwnerInfo.setOwnerName(user.getUserName());
        tpBuildingOwnerInfo.setOwnerTel(user.getLoginName());
        tpBuildingOwnerInfo.setGender(user.getGender());
        // tpBuildingOwnerInfo.setUpdateUser(userId);
        tpBuildingOwnerInfo.setUpdateDate(new Date());
        tpBuildingOwnerInfo.setCreateDate(new Date());
        // tpBuildingOwnerInfo.setCreateUser(userId);
        tpBuildingOwnerInfo.setVerifyStatus("1");
        tpBuildingOwnerInfo.setPairStatus("1");
        tpBuildingOwnerInfo.setTaUserVerifyId(taUserVerify.getId());

        // 添加的时候, 默认是当前操作的小区
        tpBuildingOwnerInfo.setCommunityId(userElement.getCommunityId());

        int row = tpBuildingOwnerInfoMapper.insertSelective(tpBuildingOwnerInfo);
        if (row <= 0) {
            log.error("添加操作! 楼栋业主信息表 失败!");
            throw new WisdomException("操作失败!");
        }
        return tpBuildingOwnerInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean updateTenantsOrDependents(String userName, String phone, String gender, Integer currentUserId, Integer type, Integer userId, String idCard) {
        ResponseBean response = new ResponseBean();

        TaUser taUser = taUserMapper.selectByPrimaryKey(currentUserId);
        if (null == taUser) {
            response.addError("当前用户不存在!");
            return response;
        }
//        if (taUser.getVerifyStatus().equals("0") || taUser.getVerifyStatus().equals("2")) {
//            response.addError("对不起,您未认证或认证已作废!");
//            return response;
//        }
        // 当前用户的身份
        TaSysRole role = taSysRoleMapper.findRoleByUserId(taUser.getId());
        if (!"OWNER".equals(role.getRoleName())) {
            response.addError("对不起,您不是业主,不能修改家属或租客!");
            return response;
        }

        int tempType = type;
        if (tempType != 2 && type != 3) {
            response.addError("对不起! 您只能修改家属或者租客!");
            return response;
        }

        if (StringUtils.isEmpty(idCard)) {
            response.addError("对不起! 身份证不允许为空!");
            return response;
        }

        TaUser user = taUserMapper.selectByPrimaryKey(userId);
        user.setUserName(userName);
        user.setLoginName(phone);
        user.setGender(gender);
        user.setUpdateDate(new Date());
        user.setUpdateUser(currentUserId);
        user.setParentId(currentUserId);
        user.setIdCard(idCard);
        if (StringUtils.isEmpty(userName)) {
            user.setUserName(user.getLoginName());
        }
        user.setBuildingOwnerInfoId(taUser.getBuildingOwnerInfoId());
        user.setCommunityId(taUser.getCommunityId());

        int result = taUserMapper.updateByPrimaryKeySelective(user);
        if (result < 0) {
            response.addError("修改失败!");
            return response;
        }
        // 修改用户
        addOrUpdateUserRole(type, response, user, false);

        // 推送海康
       //  updateUser(response, user, );

        // 下发门禁权限
//         HKOpenApi.downloadAuthorityByDeviceUuids();
        return response;
    }

    /**
     * 获取设备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());
    }



    /**
     * 公共方法
     * 修改人员
     *
     * @param response
     * @param user
     */
    private void updateUser(ResponseBean response, TaUser user, Integer communityId) {
        TpEquipmentTree tpEquipmentTree = tpEquipmentTreeMapper.selectByCommunityId(communityId);

        Map<String, Object> parDept = Maps.newHashMap();
        parDept.put("pageNo", 1);
        parDept.put("pageSize", 100);
        parDept.put("deptName", Constant.DEPT_RESIDENTS);
        // 部门UUID
        String deptUuid = getDeptUUID(parDept);

        // 人员参数
        Map<String, Object> parUser = Maps.newHashMap();
        parUser.put("personNo", user.getHkPersonNo());
        parUser.put("personId", user.getHkUserId());
        parUser.put("personName", user.getUserName());
        parUser.put("phoneNo", user.getLoginName());
        parUser.put("deptUuid", deptUuid);
        parUser.put("openapi_ip_port_http", tpEquipmentTree.getHttpServer());
        Map<String, Object> resultMap = JSONObject.parseObject(HKOpenApi.updateUser(parUser), HashMap.class);
        int errorCode = (int) resultMap.get("errorCode");
        if (errorCode == 0) {
            response.addSuccess("操作成功!");
        } else {
            String errorMessage = String.valueOf(resultMap.get("errorMessage"));
            response.addError(errorMessage);
            log.error("海康修改人员失败! {}", errorMessage);
            throw new RuntimeException(errorMessage);
        }
    }

    /**
     * 获取部门 uuid
     * <p>
     * 这里的部门相当于 小区
     *
     * @return
     */
    private String getDeptUUID(Map<String, Object> parDept) {
        Map<String, Object> deptMap = JSONObject.parseObject(HKOpenApi.getDeptName(parDept), HashMap.class);
        Map<String, Object> deptDataMap = (Map<String, Object>) deptMap.get("data");
        JSONArray jsonArray = (JSONArray) deptDataMap.get("list");
        Map<String, Object> deptListData = (Map<String, Object>) jsonArray.get(0);
        // 部门UUID
        String deptUuid = (String) deptListData.get("deptUuid");
        return deptUuid;
    }



    /**
     * 公共方法,添加或者修改 角色.
     * 用于注册 和 业主添加家属和租客
     * <p>
     * 用户登录注册的时候,没有匹配到 资料库, 就定为 未认证角色!
     *
     * @param type     1是业主 2 是租客  3 是家属 4 未认证
     * @param response
     * @param user
     * @param bool     true 添加 false 修改
     */
    private void addOrUpdateUserRole(Integer type, ResponseBean response, TaUser user, boolean bool) {
        // 先查询角色 在角色关联记录
        // 这里的 2 或者 3 或者 4 是对应角色编号
        int typeId = type.intValue();
        int roleType = typeId == 1 ? 1 : typeId == 2 ? 2 : typeId == 3 ? 3 : 4;
        TaSysRole taSysRole = taSysRoleMapper.selectByPrimaryKey(roleType);
        if (null == taSysRole) {
            response.addError("该权限不存在!");
            log.error("这个角色没有找到! 角色编号:{}", roleType);
            return;
        }

        TaSysUserRole taSysUserRole = new TaSysUserRole();
        taSysUserRole.setCommunityId(user.getCommunityId());
        taSysUserRole.setRoleId(taSysRole.getId());
        taSysUserRole.setUserId(user.getId());

        String resultSuccess = bool == true ? "添加成功!" : "修改成功!";
        String errorSuccess = bool == true ? "业主或者租客或者家属或者未认证角色权限添加失败" : "业主或者租客或者家属或者未认证角色权限修改失败";
        try {
            int resultRole = 0;
            if (bool) {
                resultRole = taSysUserRoleMapper.insertSelective(taSysUserRole);
            } else {
                Map<String, Object> map = Maps.newHashMap();
                map.put("communityId", user.getCommunityId());
                map.put("userId", user.getId());
                // 查询角色出数据
                TaSysUserRole userRole = taSysUserRoleMapper.selectByCommunityIdAndUserId(map);
                userRole.setRoleId(taSysRole.getId());
                // 修改角色
                resultRole = taSysUserRoleMapper.updateByPrimaryKeySelective(userRole);
            }
            if (resultRole > 0) {
                response.addSuccess(resultSuccess);
            } else {
                throw new RuntimeException(errorSuccess);
            }
        } catch (Exception e) {
            response.addSuccess(resultSuccess);
            log.error(errorSuccess, e);
            throw new RuntimeException(errorSuccess);
        }
    }

    @Transactional
    @Override
    public ResponseBean modifyUserHeadPortrait(Integer currentUserId, String headPortrait) {

        ResponseBean response = new ResponseBean();

        TaUser user = taUserMapper.selectByPrimaryKey(currentUserId);
        user.setHeadPortrait(headPortrait);

        int result = taUserMapper.updateByPrimaryKeySelective(user);
        if (result > 0) {
            response.addSuccess("修改成功!");
        } else {
            response.addError("修改失败!");
        }

        return response;
    }

    @Override
    public ResponseBean getUserInfo(UserElement userElement, Integer userId, Integer userVerifyId, HttpSession session) {

        ResponseBean response = new ResponseBean();

        // 获取用户
        TaUser user = taUserMapper.selectByPrimaryKey(userElement.getId());
        if (null == user) {
            response.addError("用户不存在！");
            return response;
        }

        // 校验房产
        checkLogin(response, user, session);

        // 校验用户
        checkBlacklistStatusUser(user);

        // 当没有可以选择的房产时
        if (((TaUserVO)response.getData()).getUserVerifyList().size() == 0) {
            // 当 解除了这个房产关联关系的时候，就不能获取到用户信息
            TaUserVerify userVerify = taUserVerifyMapper.selectByPrimaryKey(userElement.getUserVerifyId());
            if (null == userVerify ) {
                response.addError("无关联该房产");
                return response;
            }
        }

        user.setUserVerifyId(userElement.getUserVerifyId());
        user.setCommunityId(userElement.getCommunityId());

        // 查询 家属或者租客
        if (null != userId) {
            List<TaUserVerify> todUserVerify = taUserVerifyMapper.selectCommunityAndAddress(userId, userElement.getCommunityId(), userElement.getPhaseId(), userElement.getBuildingId(), userElement.getUnitId(), userElement.getLevelId(), userElement.getRoomNoId(), null);
            // 判断 家属或者租客 属不属于这个业主的下面
            if (null == todUserVerify || todUserVerify.size() == 0) {
                response.addError("您的下面没有该家属或者租客!");
                return response;
            }
            boolean anyMatch = todUserVerify.stream().anyMatch(e -> e.getId().intValue() == userVerifyId.intValue());
            if (!anyMatch) {
                response.addError("您的下面没有该家属或者租客!");
                return response;
            }
            TaUser todUser = taUserMapper.selectByPrimaryKey(userId);
            todUser.setUserVerifyId(userVerifyId);
            todUser.setCommunityId(userElement.getCommunityId());
            user = todUser;
        }


        if (null != user.getUserVerifyId() && null != user.getCommunityId()) {
            TaUserVO userVO = new TaUserVO();
            // 根据用户id, 获取 用户的住址, 人脸是否认证, 角色
            userSetUp(user, userVO);
            userVO.setUserVerifyList(((TaUserVO)response.getData()).getUserVerifyList());
            TaUserVerify userVerify = taUserVerifyMapper.selectByPrimaryKey(userVerifyId);
            // 审核不通过的原因, 在查看业主查看房屋成员的时候！如果有这个值，就取出来
            if (null != userVerify) {
                userVO.setRemark(userVerify.getRemark());
            }
            response.setUrl(null);
            response.addSuccess(userVO);
        }
        return response;
    }

    /**
     * 根据用户id, 获取 用户的住址, 人脸是否认证, 角色
     *
     * @param user
     * @param userVO
     */
    private TaUserVO userSetUp(TaUser user, TaUserVO userVO) {

        BeanTools.copyProperties(user, userVO);

        // 默认未绑定微信
        userVO.setBindingWX(Constant.NO_BINDING_WX);

        // 如果存在值，则已绑定微信
        if (StringUtils.isNotBlank(user.getOpenid())) {
            userVO.setBindingWX(Constant.BINDING_WX);
        }

        /**
         * 获取楼栋信息，不能 根据 app用户表的楼栋资料库id 来获取，要根据当前登录的 房产id 来查询 app审核表  获取，用户 session 里面有 房产id
         */


        // 根据 审核id 查询 出审核的数据，里面有角色id
        TaUserVerify userVerify = taUserVerifyMapper.selectByPrimaryKey(user.getUserVerifyId());

        userVO.setPhaseId(userVerify.getPhaseId());
        userVO.setBuildingId(userVerify.getBuildingId());
        userVO.setUnitId(userVerify.getUnitId());
        userVO.setLevelId(userVerify.getLevelId());
        userVO.setRoomNoId(userVerify.getRoomNoId());

        // 房产状态
        userVO.setVerifyStatus(userVerify.getVerifyStatus());

        userVO.setAddressBuilding(userVerify.getPhaseName() + userVerify.getBuildingName() + userVerify.getUnitName() + userVerify.getLevelName() + userVerify.getRoomNoName());

        // 角色
        TaSysRole taSysRole = taSysRoleMapper.selectByPrimaryKey(userVerify.getRoleId());
        userVO.setRole(taSysRole.getRoleName());

        // 设置 userVO 一些信息
        setUserVoProperties(user.getCommunityId(), userVO);

        // 人脸是否已录入
        TaFace face = taFaceMapper.getByUserVerifyId(userVerify.getId());
        if (null != face) {
            userVO.setFace("register");
        } else {
            userVO.setFace("unregister");
        }

        /**
         * 获取 业主的信息，只能根据 审核表，获取 楼栋信息，来查询出当前房产的 业主是谁
         */

        TaUserVerify ownerUserVerify = taUserVerifyMapper.selectCommunityAndAddressAndRoleId(user.getCommunityId(), userVerify.getPhaseId(), userVerify.getBuildingId(), userVerify.getUnitId(), userVerify.getLevelId(), userVerify.getRoomNoId());
        // 存在这个房产没有业主的情况
        if (null != ownerUserVerify) {
            TpBuildingOwnerInfo tpBuildingOwnerInfo = tpBuildingOwnerInfoMapper.selectByUserVerifyId(ownerUserVerify.getId());
            if (null != tpBuildingOwnerInfo) {
                userVO.setProprietorID(ownerUserVerify.getUserId());
                userVO.setProprietorPhone(tpBuildingOwnerInfo.getOwnerTel());
                userVO.setProprietorName(tpBuildingOwnerInfo.getOwnerName());
            }
        }


        return userVO;
    }

    @Override
    public ResponseBean temporaryLogin(HttpSession session) {
        ResponseBean responseBean = new ResponseBean();

        TaUser currentUser = hasUserPhone(loginCodePerproties.getPhone());
        if (null == currentUser) {
            responseBean.addError("账号不存在!");
            return responseBean;
        }

        // 检验登录房产
        checkLogin(responseBean, currentUser, session);
        return responseBean;
    }

    @Override
    public ResponseBean addWelcomeUser(UserElement userElement, TaUser user) {
        ResponseBean responseBean = new ResponseBean();

        TaUser currentUser = taUserMapper.selectByPrimaryKey(userElement.getId());

        user.setBuildingOwnerInfoId(currentUser.getBuildingOwnerInfoId());
        user.setCommunityId(userElement.getCommunityId());
        user.setParentId(userElement.getId());
        user.setCreateDate(new Date());
        user.setCreateUser(userElement.getId());
        user.setCommunityId(userElement.getCommunityId());
        user.setVerifyStatus("1");
        user.setAcceptAgreementStatus("1");
        user.setFaceStatus("0");
        user.setStatus("1");

        int rows = taUserMapper.insertSelective(user);
        if (rows <= 0) {
            responseBean.addError("操作失败！");
            return responseBean;
        }

        // 角色  2 表示租客
        addOrUpdateUserRole(2, responseBean, user, true);
        responseBean.addSuccess(user);
        return responseBean;
    }

    @Override
    public ResponseBean bindingLoginAndHouse(UserElement userElement, Integer userVerifyId) {
        ResponseBean responseBean = new ResponseBean();
        TaUserVO taUserVO = new TaUserVO();
        TaUserVerify userVerify = taUserVerifyMapper.selectByPrimaryKey(userVerifyId);
        if (null != userVerify) {
            if (userElement.getId().intValue() != userVerify.getUserId().intValue()) {
                throw new WisdomException("您未绑定该房产！");
            }
            TaUser currentUser = taUserMapper.selectByPrimaryKey(userElement.getId());

            // 校验房产
            List<TaUserVerify> taUserVerifies = taUserVerifyMapper.selectByUserId(currentUser.getId());
            taUserVerifies.forEach(e->{
                e.setVerifyUrl(loginCodePerproties.getLoginCode().get("-1") + e.getId());
            });
            taUserVO.setUserVerifyList(taUserVerifies);
            BeanUtils.copyProperties(currentUser, taUserVO);
            return checkHouse(responseBean, taUserVO, userVerify);
        }
        throw new WisdomException("该房产不存在！");
    }

    /**
     * 校验 房产的状态
     *
     * @param responseBean
     * @param taUserVO
     * @param userVerify
     * @return
     */
    private ResponseBean checkHouse(ResponseBean responseBean, TaUserVO taUserVO, TaUserVerify userVerify) {
        // 设置 这个审核id （这个要返给前端）
        taUserVO.setUserVerifyId(userVerify.getId());
        taUserVO.setVerifyStatus(userVerify.getVerifyStatus());

        // 认证状态  0 是未审核   1是审核通过   2是审核不通过
        String verifyStatus = userVerify.getVerifyStatus();
        // 有一个审核通过的房产
        if ("1".equals(verifyStatus)) {
            // 设置 userVO 信息
            setUserVoProperties(userVerify.getCommunityId(), taUserVO);
            taUserVO.setPhaseId(userVerify.getPhaseId());
            taUserVO.setBuildingId(userVerify.getBuildingId());
            taUserVO.setUnitId(userVerify.getUnitId());
            taUserVO.setLevelId(userVerify.getLevelId());
            taUserVO.setRoomNoId(userVerify.getRoomNoId());
            taUserVO.setAddressBuilding(userVerify.getPhaseName() + userVerify.getBuildingName() + userVerify.getUnitName() + userVerify.getLevelName() + userVerify.getRoomNoName());

            // 人脸是否已录入
            TaFace face = taFaceMapper.getByUserVerifyId(userVerify.getId());
            if (null != face) {
                taUserVO.setFace("register");
            } else {
                taUserVO.setFace("unregister");
            }

            TaSysRole taSysRole = taSysRoleMapper.selectByPrimaryKey(userVerify.getRoleId());
            taUserVO.setRole(taSysRole.getRoleName());

            responseBean.addSuccess(UserVerifyEnum.A_AUDIT_REAL_ESTATE.getMsg(), taUserVO, loginCodePerproties.getLoginCode().get(UserVerifyEnum.A_AUDIT_REAL_ESTATE.getCode()));
            return responseBean;
        }
        String resultCode = "0".equals(verifyStatus) ? UserVerifyEnum.A_TO_AUDIT_REAL_ESTATE.getCode() :
                "2".equals(verifyStatus) ? UserVerifyEnum.A_AUDIT_FAILED_REAL_ESTATE.getCode() : "500";
        responseBean.addError(UserVerifyEnum.getMsg(resultCode), taUserVO, loginCodePerproties.getLoginCode().get("-1") + taUserVO.getUserVerifyId());
        return responseBean;
    }

    @Override
    public TaUser hasUserPhone(String phone) {
        // 校验手机号
        iCode.checkPhone(phone);

        Map<String, Object> map = Maps.newHashMap();
        map.put("loginName", phone);
        TaUser currentUser = taUserMapper.selectByLoginName(map);
        return currentUser;
    }

    @Override
    public ResponseBean hasUserPhoneVerify(String phone, UserElement userElement) {
        ResponseBean responseBean = new ResponseBean();
        TaUser user = hasUserPhone(phone);
        if (null == user) {
            responseBean.addError("未注册");
            return responseBean;
        }

        TaUserVO userVO = new TaUserVO();
        BeanTools.copyProperties(user, userVO);
        List<TaUserVerify> userVerifyList = taUserVerifyMapper.selectCommunityAndAddress(user.getId(), userElement.getCommunityId(), userElement.getPhaseId(), userElement.getBuildingId(), userElement.getUnitId(), userElement.getLevelId(), userElement.getRoomNoId(), 1);
        if (null != userVerifyList && userVerifyList.size() > 0) {
            TaFace face = taFaceMapper.getByUserVerifyId(userVerifyList.get(0).getId());
            if (null == face) {
                userVO.setFace("register");
            } else {
                userVO.setFace("unregister");
            }
        }

        responseBean.addSuccess(userVO);
        return responseBean;
    }

    @Override
    public ResponseBean deleteTenantAndRelation(UserElement userElement, Integer userVerifyId) {
        ResponseBean responseBean = new ResponseBean();

        // 1.查询出要删除的房产
        // 2.判断房产是否属于 这个 业主

        // 被删除的房产（也就是家属或者租客 在审核表里面的id）
        TaUserVerify userVerify = taUserVerifyMapper.selectByPrimaryKey(userVerifyId);
        if (null == userVerify) {
            responseBean.addError("房产不存在！");
            return responseBean;
        }

        // 业主的
        TaUserVerify ownerUserVerify = taUserVerifyMapper.selectCommunityAndAddressAndRoleId(userElement.getCommunityId(), userElement.getPhaseId(), userElement.getBuildingId(), userElement.getUnitId(), userElement.getLevelId(), userElement.getRoomNoId());

        // 如果业主删除房屋成员(也就是删除房产审核)，房产的业主id 和 当前登录的业主的id，相等的时候才允许删除(相等才能表示是这个业主的房产)
        if (ownerUserVerify.getUserId().intValue() == userElement.getId()) {
            taUserVerifyMapper.deleteByPrimaryKey(userVerifyId);
        }

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

    @Override
    public ResponseBean daSuToken(String appid, String datetime, String encrypt, String communityId, String phone, String sign, HttpSession session) {
        ResponseBean responseBean = new ResponseBean();

        LocalDateTime currrenDate = LocalDateTime.now();
        LocalDateTime parameDate = Instant.ofEpochMilli(Long.parseLong(datetime)).atZone(ZoneId.systemDefault()).toLocalDateTime();

        long minutes = Duration.between(parameDate, currrenDate).toMinutes();
        if (minutes > 10) {
            responseBean.addError("签名已过期!");
            return responseBean;
        }


        // server 端签名
        String serverSign = DaSuSign.createSign(daSuProperties.getAppid(), daSuProperties.getAppSecret(), datetime, encrypt, communityId, phone);
        boolean isMd5Sign = DaSuSign.isMD5Sign(serverSign, sign);
        if (!isMd5Sign) {
            responseBean.addError("签名错误!");
            return responseBean;
        }

        if (!daSuProperties.getCommunityId().equals(communityId)) {
            responseBean.addError("小区不正确!");
            return responseBean;
        }

        if (!daSuProperties.getAppid().equals(appid)) {
            responseBean.addError("appid 不正确!");
            return responseBean;
        }

        TaUser currentUser = hasUserPhone(phone);
        if (null == currentUser) {
            responseBean.addError("未注册，请先注册！请先调用用户添加接口");
            return responseBean;
        }

        // 检验登录房产
        checkLogin(responseBean, currentUser, session);
        return responseBean;
    }
}
