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.huiju.common.hk.HKConstant;
import com.community.huiju.common.hk.HKOpenApi;
import com.community.huiju.common.perproties.LoginCodePerproties;
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.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 java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.logging.SimpleFormatter;

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 TpBuildingOwnerInfoMapper tpBuildingOwnerInfoMapper;

    @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;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean login(String loginName, String code) {
        ResponseBean response = new ResponseBean();

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

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

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

        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");

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

        // 开始注册
        user.setCreateDate(new Date());
        user.setUpdateDate(new Date());
        user.setStatus("1");
        user.setAcceptAgreementStatus("1");
        user.setUserName(user.getUserName());
        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) {
        // 校验用户
        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);
        }


        // 校验房产
        List<TaUserVerify> taUserVerifies = taUserVerifyMapper.selectByUserId(currentUser.getId());
        // 无关联房产
        if (null == taUserVerifies || taUserVerifies.size() == 0) {
            response.addSuccess(UserVerifyEnum.NO_AUDIT_REAL_ESTATE.getMsg(), taUserVO, loginCodePerproties.getLoginCode().get(UserVerifyEnum.NO_AUDIT_REAL_ESTATE.getCode()));
            return response;
        }

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

            /**
             * 这个 审核id 很重要，后面的角色，都是根据这个 审核id 查询的，
             * 登陆成功后这个 审核id 会存 session
             */

            return checkHouse(response, taUserVO, userVerify);
        } else if (taUserVerifies.size() >= 2) {
            response.addSuccess(UserVerifyEnum.A_MULTIPLE_REAL_ESTATE.getMsg(), taUserVO, loginCodePerproties.getLoginCode().get(UserVerifyEnum.A_MULTIPLE_REAL_ESTATE.getCode()));
            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());
    }

    /**
     * 可视对讲下发
     *
     * @param user
     */
    private void visualIntercom(TaUser user) {
        // TODO 目前下发的 authName权限组是我们自定义的, 后面肯定是按照小区的 期楼栋号来设置的
        // TODO longNums设备编号, 可视对讲的机器编号, 应该根据 期楼栋号 下面的机器编号来设置的

        //--------- 可视对讲 ----------

        // 可视对讲 根据人员 ID 集添加权限并下发
        Map<String, Object> addOutDoorAuthMap = new HashMap<>();
        addOutDoorAuthMap.put("authName", "荟居");
        addOutDoorAuthMap.put("personIds", Arrays.asList(user.getHkUserId()));
        addOutDoorAuthMap.put("longNums", Arrays.asList("10010100000"));
        // 可视对讲 根据人员 ID 集添加权限并下发
        HKOpenApi.addOutDoorAuth(addOutDoorAuthMap);

        // 可视对讲 指定人员指纹权限下载
//        Map<String, Object> downloadFingerMap = new HashMap<>();
//        // opType 操作类型 Integer 是 1 为下发权限；2 为删除权限
//        downloadFingerMap.put("opType", 1);
//        downloadFingerMap.put("personIds", Arrays.asList(user.getHkUserId()));
//        downloadFingerMap.put("longNums", Arrays.asList("10010100000"));
//        // 可视对讲 指定人员指纹权限下载
//        HKOpenApi.downloadFinger(downloadFingerMap);

    }

    @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;
        }
        String data = HKOpenApi.HKpersonPhone(user.getHkUserId(), user.getHkPersonNo(), user.getUserName(), phone);
        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());

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

        TaSysRole sysRole = taSysRoleMapper.selectByPrimaryKey(userElement.getUserVerifyId());

        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())) {
            // 用户数据查询出来
            user = taUserMapper.selectByPrimaryKey(user.getId());
        } else {
            user = (TaUser) response.getData();
        }

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


        // 开始存入审核表
        TaUserVerify userVerify = new TaUserVerify();
        userVerify.setVerifyStatus("1");
        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());

        taUserVerifyMapper.insertSelective(userVerify);

        // 设置 海康id
        user.setHkPersonNo(idGen.nextId());


        // 推送海康
        /**
         * 1.获取部门(比如 住户)
         * 2.根据部门编号推送 海康
         */
        addUserAndOpenCard(response, user);

        // 给用户添加 海康门禁权限
        HKOpenApi.addAuthoritiesByPersonIds(String.valueOf(user.getHkUserId()));

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

        //--------- 可视对讲 ----------
        visualIntercom(user);

        if ("0".equals(response.getCode())) {
            response.addSuccess(user);
        }

        return response;
    }

    @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;
    }

    /**
     * 公共方法
     * 添加人员, 开卡
     *
     * @param response
     * @param user
     */
    private void addUserAndOpenCard(ResponseBean response, TaUser user) {
        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("personName", user.getUserName());
        parUser.put("phoneNo", user.getLoginName());
        parUser.put("deptUuid", deptUuid);
        Map<String, Object> resultMap = JSONObject.parseObject(HKOpenApi.addUser(parUser), HashMap.class);
        int errorCode = (int) resultMap.get("errorCode");
        if (errorCode == 0) {
            Map<String, Object> resultDataMap = (Map<String, Object>) resultMap.get("data");
            // 开卡 卡号
            long cardNo = System.currentTimeMillis();
            // 海康人员ID
            Integer personId = (Integer) resultDataMap.get("personId");
            TaUser tempUser = taUserMapper.selectByPrimaryKey(user.getId());
            tempUser.setHkUserId(personId);
            tempUser.setHkCardNo(cardNo + "");

            user.setHkUserId(personId);
            // 存储海康人员ID
            int row = taUserMapper.updateByPrimaryKeySelective(tempUser);
            if (row > 0) {
                response.addSuccess("操作成功!");
            } else {
                response.addError("操作失败");
                throw new RuntimeException("数据库添加 家属/租客 人员失败!");
            }

            // 开卡
            List<String> cardAndPersonList = Lists.newArrayList();
            cardAndPersonList.add(cardNo + "," + personId);
            response = openCard(cardAndPersonList, null);
        } else {
            String errorMessage = String.valueOf(resultMap.get("errorMessage"));
            response.addError(errorMessage);
            log.error("海康添加人员失败! {}", errorMessage);
            throw new RuntimeException(errorMessage);
        }
    }

    /**
     * 公共方法
     * 修改人员
     *
     * @param response
     * @param user
     */
    private void updateUser(ResponseBean response, TaUser user) {
        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);
        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;
    }

    /**
     * 批量开卡
     *
     * @param cardIdAndHKUserID list.add("卡号,人员ID")
     * @param expirationTime    有效期为多少? 单位为 年
     * @return
     */
    private ResponseBean openCard(List<String> cardIdAndHKUserID, Integer expirationTime) {
        ResponseBean response = new ResponseBean();

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        LocalDate today = LocalDate.now();
        int year = today.getYear();
        // 加上20, 表示加上20年,默认
        if (null == expirationTime || expirationTime <= 0) {
            year += 20;
        } else {
            year += expirationTime;
        }
        int month = today.getMonthValue();
        int day = today.getDayOfMonth();

        Long time = null;
        try {
            time = formatter.parse(year + "-" + month + "-" + day).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }

        // 开卡
        Map<String, Object> parOpenCard = Maps.newHashMap();
        parOpenCard.put("cardAndPerson", cardIdAndHKUserID);
        parOpenCard.put("startTime", System.currentTimeMillis());
        parOpenCard.put("endTime", time);
        JSONObject openCardJSON = JSONObject.parseObject(HKOpenApi.openCard(parOpenCard));
        int code = (int) openCardJSON.get("errorCode");
        if (code == 0) {
            response.addSuccess("操作成功!");
        } else {
            String errorMessage = String.valueOf(openCardJSON.get("errorMessage"));
            response.addError(errorMessage);
            log.error("开卡失败! {}", errorMessage);
            throw new RuntimeException(errorMessage);
        }

        return response;
    }

    /**
     * 公共方法,添加或者修改 角色.
     * 用于注册 和 业主添加家属和租客
     * <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) {

        ResponseBean response = new ResponseBean();

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

        // 校验用户
        checkBlacklistStatusUser(user);

        // 当 解除了这个房产关联关系的时候，就不能获取到用户信息
        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;
        }


        TaUserVO userVO = new TaUserVO();

        // 根据用户id, 获取 用户的住址, 人脸是否认证, 角色
        userSetUp(user, userVO);

        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.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");
        }

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

        // TODO 楼栋资料库查询有变动
        TpBuildingOwnerInfo tpBuildingOwnerInfo = tpBuildingOwnerInfoMapper.selectCommunityIdAndAddress(user.getCommunityId(), userVerify.getPhaseId(), userVerify.getBuildingId(), userVerify.getUnitId(), userVerify.getLevelId(), userVerify.getRoomNoId());

        if (null != tpBuildingOwnerInfo) {
            //查询当前人业主或租客的信息
            Map<String, Object> map = Maps.newHashMap();
            map.put("loginName", tpBuildingOwnerInfo.getOwnerTel());
            TaUser proprietorUser = taUserMapper.selectByLoginName(map);
            userVO.setProprietorID(proprietorUser.getId());
            userVO.setProprietorPhone(proprietorUser.getLoginName());
            userVO.setProprietorName(proprietorUser.getUserName());
        }

        return userVO;
    }

    @Override
    public ResponseBean temporaryLogin(Integer communityId) {
        ResponseBean responseBean = new ResponseBean();
        ToCommunities communities = toCommunitiesMapper.selectByPrimaryKey(communityId);
        if (null == communities) {
            responseBean.addError("小区不存在!");
            return responseBean;
        }

        // 游客用户
        TaUser user = taUserMapper.selectByPrimaryKey(-1);

        TaUserVO taUserVO = new TaUserVO();
        BeanUtils.copyProperties(user, taUserVO);
        taUserVO.setCommunityId(communityId);
        taUserVO.setRole("游客");
        taUserVO.setCommunityName(communities.getCommunityName());

        responseBean.addSuccess(taUserVO);

        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());
            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());

        // 认证状态  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.addSuccess(UserVerifyEnum.getMsg(resultCode), taUserVO, loginCodePerproties.getLoginCode().get(resultCode));
        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);

        // TODO 楼栋资料库查询有变动
        // 查询出要被删除的房产的 楼栋资料信息
        TpBuildingOwnerInfo buildingOwnerInfo = tpBuildingOwnerInfoMapper.selectCommunityIdAndAddress(userElement.getCommunityId(), userVerify.getPhaseId(), userVerify.getBuildingId(), userVerify.getUnitId(), userVerify.getLevelId(), userVerify.getRoomNoId());
        TaUser currentUser = hasUserPhone(buildingOwnerInfo.getOwnerTel());

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

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