package com.yihu.jw.base.service.user;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.jw.base.dao.equipment.WlyyUserAreaDao;
import com.yihu.jw.base.dao.equipment.WlyyUserEquipmentDao;
import com.yihu.jw.base.dao.role.BaseRoleMenuDao;
import com.yihu.jw.base.dao.role.RoleDao;
import com.yihu.jw.base.dao.saas.SaasDao;
import com.yihu.jw.base.dao.user.UserDao;
import com.yihu.jw.base.service.org.*;
import com.yihu.jw.base.util.ConstantUtils;
import com.yihu.jw.base.util.JavaBeanUtils;
import com.yihu.jw.entity.base.org.BaseOrgUserDO;
import com.yihu.jw.entity.base.role.RoleDO;
import com.yihu.jw.entity.base.saas.SaasDO;
import com.yihu.jw.entity.base.user.UserDO;
import com.yihu.jw.entity.equipment.WlyyUserAreaDO;
import com.yihu.jw.entity.equipment.WlyyUserEquipmentDO;
import com.yihu.jw.entity.hospital.consult.WlyyHospitalSysDictDO;
import com.yihu.jw.hospital.dict.WlyyHospitalSysDictDao;
import com.yihu.jw.restmodel.base.wx.WxGraphicMessageVO;
import com.yihu.jw.restmodel.base.wx.WxReplySceneVO;
import com.yihu.jw.util.date.DateUtil;
import com.yihu.jw.utils.hibernate.HibenateUtils;
import com.yihu.mysql.query.BaseJpaService;
import com.yihu.utils.security.MD5;
import org.apache.axis.utils.Admin;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.sql.PreparedStatement;
import java.util.*;
import java.util.logging.Logger;

/**
 * Service - 后台管理员
 * Created by progr1mmer on 2018/8/20.
 */
@Service
public class UserService extends BaseJpaService<UserDO, UserDao> {

    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private SaasDao saasDao;
    @Autowired
    private BaseRoleMenuDao baseRoleMenuDao;
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private BaseOrgUserService baseOrgUserService;

    @Autowired
    private OrgTreeService orgTreeService;

    @Autowired
    private WlyyUserAreaDao userAreaDao;
    @Autowired
    private WlyyUserEquipmentDao userEquipmentDao;
    
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private HibenateUtils hibenateUtils;

    @Value("${configDefault.saasId}")
    private String defaultSaasId;
    
    @Autowired
    private WlyyHospitalSysDictDao wlyyHospitalSysDictDao;

    @Value("${wechat.flag}")
    private boolean flag;


    public UserDO registerWithIdcard(UserDO userDO) {
        userDO.setSalt(randomString(5));
        if (StringUtils.isEmpty(userDO.getEnabled())){
            userDO.setEnabled(true);
        }else {
            userDO.setEnabled(userDO.getEnabled());
        }
        userDO.setLocked(false);
        userDO.setLoginFailureCount(0);
        String password = userDO.getPassword();
        if (StringUtils.isEmpty(password)) {
            password = userDO.getIdcard().substring(userDO.getIdcard().length()-6,userDO.getIdcard().length());
        }
        userDO.setPassword(MD5.md5Hex(password + "{" + userDO.getSalt() + "}"));
        return userDao.save(userDO);
    }

    /**
     * 手机号作为账号，初始密码为手机号后6位
     *
     * @param userDO
     * @return
     */
    public UserDO registerWithMobile(UserDO userDO) {
        userDO.setSalt(randomString(5));
        userDO.setEnabled(true);
        userDO.setLocked(false);
        userDO.setLoginFailureCount(0);
        String password = userDO.getPassword();
        if (StringUtils.isEmpty(password)) {
            password = userDO.getMobile().substring(userDO.getMobile().length()-6, userDO.getMobile().length());
        }
        userDO.setPassword(MD5.md5Hex(password + "{" + userDO.getSalt() + "}"));
        return userDao.save(userDO);
    }


    /**
     * 根据用户手机号查找（手机号为登录账号）
     *
     * @param mobile
     * @return
     */
    public UserDO findByMobile(String mobile) {
        return userDao.findByMobile(mobile);
    }

    /**
     * 根据id查找用户
     *
     * @param id
     * @return
     */
    public UserDO findById(String id) {
        return userDao.findById(id);
    }

    /**
     * 判断手机号是否存在
     *
     * @param mobile
     * @return
     */
    public Boolean existMobile(String mobile) {
        if (StringUtils.isEmpty(mobile)) {
            return null;
        }
        return userDao.existsByMobile(mobile);
    }

    /**
     * 判断用户名是否存在
     * @param username
     * @return
     */
    public Boolean existUserName(String username){
        if(StringUtils.isEmpty(username)) {
            return null;
        }
        return userDao.existsByUsername(username);
    }

    /**
     * 用户管理，获取用户基本信息列表
     *
     * @param name   模糊查询
     * @param saasId 精准匹配，为空查全部
     * @param roleId 精准匹配，为空查全部
     * @return
     */
    public List<Map<String, Object>> queryBaseUserInfoList(String name, String saasId, String roleId) {
        List<Map<String, Object>> result = new ArrayList<>();
        return result;
    }

    public Map<String, Object> findUserBaseInfo(String id) throws Exception {

        Map<String, Object> userinfo = new HashedMap();

        UserDO user = userDao.findOne(id);
        RoleDO role = null;
        if (user != null ) {
            if(!user.getEnabled()){
                throw new Exception("用户已失效！");
            }
            userinfo.put("id", user.getId());
            userinfo.put("name", user.getName());
            role = roleDao.findOne(user.getRoleId());
        }
        //获取角色
        if (role != null) {
            userinfo.put("role", role.getId());
            userinfo.put("roleCode", role.getCode());
            userinfo.put("system", role.getSystem());

            if (role.getType()==1) {
                //平台管理员信息获取

            } else if (role.getType()==2) {
                //saas平台管理员信息获取
                if (org.apache.commons.lang3.StringUtils.isNotBlank(user.getId())) {
                    SaasDO saas = saasDao.findOne(user.getSaasId());
                    Map<String, Object> ss = new HashedMap();
                    ss.put("id", saas.getId());
                    ss.put("name", saas.getName());
                    userinfo.put("saas", ss);
                }

            } else if (role.getType()==3) {
                //機構管理員信息獲取
                String sql = "SELECT " +
                            " g.code AS orgCode, " +
                            " g.province_code AS provinceCode, " +
                            " g.province_name AS privinceName, " +
                            " g.city_code AS cityCode, " +
                            " g.city_name AS cityName, " +
                            " g.town_code AS townCode, " +
                            " g.town_name AS townName, " +
                            " g.street_code AS streetCode, " +
                            " g.street_name AS streetName, " +
                            " g.name, " +
                            " address " +
                            " FROM " +
                            " base_org g " +
                            " JOIN base_org_user u ON g.`code` = u.org_code " +
                            " WHERE  " +
                            " u.user_id = '" + id + "'";
                    List<Map<String, Object>> org = jdbcTemplate.queryForList(sql);
                    if (org != null && org.size() > 0) {
                        userinfo.put("org", org.get(0));
                    } else {
                        userinfo.put("org", null);
                    }
            }
        }
        //機構管理員信息獲取
        String sql = "SELECT " +
                " g.code AS orgCode, " +
                " g.province_code AS provinceCode, " +
                " g.province_name AS privinceName, " +
                " g.city_code AS cityCode, " +
                " g.city_name AS cityName, " +
                " g.town_code AS townCode, " +
                " g.town_name AS townName, " +
                " g.street_code AS streetCode, " +
                " g.street_name AS streetName, " +
                " g.name, " +
                " g.address " +
                " FROM " +
                " base_org g " +
                " JOIN base_org_user u ON g.code = u.org_code " +
                " WHERE  " +
                " u.user_id = '" + id + "'";
        List<Map<String, Object>> org = jdbcTemplate.queryForList(sql);
        if (org != null && org.size() > 0) {
            userinfo.put("org", org);
        } else {
            userinfo.put("org", null);
        }
    
        //密码过期
        userinfo.put("authPw",findDoctorPwlimitDate(id));

        return userinfo;
    }
    
    public com.alibaba.fastjson.JSONObject findDoctorPwlimitDate(String user){
        String key = "base:authPw:user:" + user;
        String authPw = redisTemplate.opsForValue().get(key);
        com.alibaba.fastjson.JSONObject valueJson = null;
        if(org.apache.commons.lang3.StringUtils.isNotBlank(authPw)){
            
            WlyyHospitalSysDictDO wlyyHospitalSysDictDO = wlyyHospitalSysDictDao.findById("pwOverDue");
            String code[] = wlyyHospitalSysDictDO.getDictCode().split(",");
            Integer maxDateInt = Integer.parseInt(code[0]);
            Integer remainDateInt = Integer.parseInt(code[1]);
            
            valueJson = JSON.parseObject(authPw);
            Long updateTimeLong = valueJson.getLong("updateTime");
            Date updateTime = new Date();
            updateTime.setTime(updateTimeLong);
            Date maxDate = DateUtil.getPreDays(updateTime,maxDateInt);
            
            Long betweenDate = (maxDate.getTime() - new Date().getTime())/(60*60*24*1000);
            valueJson.put("betweenDate",betweenDate);
            if(betweenDate<remainDateInt){
                valueJson.put("remaind",true);
            }else {
                valueJson.put("remaind",false);
            }
        }else {
            valueJson = new com.alibaba.fastjson.JSONObject();
            valueJson.put("isChanged",false);
        }
        return valueJson;
    }


    /**
     * 创建用户
     *
     * @param jsonData
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject createUser(String jsonData) {
        JSONObject result = new JSONObject();
        if (StringUtils.isEmpty(jsonData)) {
            result.put("msg", "parameter jsonData is null");
            result.put("response", ConstantUtils.FAIL);
            return result;
        }
        JSONObject jsonObject = JSONObject.parseObject(jsonData);
        JSONObject user = jsonObject.getJSONObject("user");
        JSONArray org = jsonObject.getJSONArray("org");
        JSONArray area = jsonObject.getJSONArray("area");
        JSONArray equipment = jsonObject.getJSONArray("equipment");

        //归属租户为默认租户，表示用户为超级管理员，不需要机构
        if (null == user || CollectionUtils.isEmpty(org) && !user.getString("saasId").equalsIgnoreCase(defaultSaasId)) {
            result.put("msg", "请点击机构管理选择所在机构");
            result.put("response", ConstantUtils.FAIL);
            return result;
        }
        //组装用户信息
        UserDO userDO = null;
        try {
            userDO = objectMapper.readValue(user.toJSONString(), UserDO.class);
        } catch (IOException e) {
            result.put("msg", "convert user jsonObject to UserDO failed," + e.getCause());
            result.put("response", ConstantUtils.FAIL);
            return result;
        }
        registerWithIdcard(userDO);

        //组装用户与机构的关联关系
        List<BaseOrgUserDO> orgList = new ArrayList<>();
        BaseOrgUserDO orgUserDO = null;
        if(!CollectionUtils.isEmpty(org)){
            for (Object obj : org) {
                try {
                    orgUserDO = objectMapper.readValue(obj.toString(), BaseOrgUserDO.class);
                    orgUserDO.setUserId(userDO.getId());
                    orgList.add(orgUserDO);
                } catch (IOException e) {
                    result.put("msg", "convert org jsonObject to BaseOrgUserDO failed," + e.getCause());
                    result.put("response", ConstantUtils.FAIL);
                    return result;
                }
            }
            baseOrgUserService.batchInsert(orgList);
        }
        //area:[{"city":"","cityName":"","town":"","townName":"","hospital":"","hospitalName":""}]
        //用户所属区域添加
        if (area!=null&&area.size()!=0){
            userAreaDao.deleteByUserId(userDO.getId());
            for (int i=0;i<area.size();i++){
                JSONObject object = area.getJSONObject(i);
                WlyyUserAreaDO userAreaDO = new WlyyUserAreaDO();
                userAreaDO.setUserId(userDO.getId());
                userAreaDO.setCity(object.getString("city"));
                userAreaDO.setCityName(object.getString("cityName"));
                userAreaDO.setTown(object.getString("town"));
                userAreaDO.setTownName(object.getString("townName"));
                if (!StringUtils.isEmpty(object.getString("hospital"))){
                    userAreaDO.setHospital(object.getString("hospital"));
                    userAreaDO.setHospitalName(object.getString("hospitalName"));
                }
                userAreaDO.setCreateTime(new Date());
                userAreaDO.setUpdateTime(new Date());
                userAreaDO.setDel(1);
                userAreaDao.save(userAreaDO);
            }
        }
        //用户所管设备添加
        //equipment:[{"equipmentId":"","equipmentName":""}]
        if (equipment!=null&&equipment.size()!=0){
            userEquipmentDao.deleteByUserId(userDO.getId());
            for (int i=0;i<equipment.size();i++){
                JSONObject object = equipment.getJSONObject(i);
                WlyyUserEquipmentDO userEquipmentDO = new WlyyUserEquipmentDO();
                userEquipmentDO.setDel(1);
                userEquipmentDO.setUserId(userDO.getId());
                userEquipmentDO.setCity(object.getString("city"));
                userEquipmentDO.setCityName(object.getString("cityName"));
                userEquipmentDO.setTown(object.getString("town"));
                userEquipmentDO.setTownName(object.getString("townName"));
                if (!StringUtils.isEmpty(object.getString("hospital"))){
                    userEquipmentDO.setHospital(object.getString("hospital"));
                    userEquipmentDO.setHospitalName(object.getString("hospitalName"));
                }
                userEquipmentDO.setEquipmentId(object.getString("equipmentId"));
                userEquipmentDO.setEquipmentName(object.getString("equipmentName"));
                userEquipmentDO.setCreateTime(new Date());
                userEquipmentDO.setUpdateTime(new Date());
                userEquipmentDao.save(userEquipmentDO);
            }
        }
        JSONObject returnMsg = new JSONObject();
        returnMsg.put("username",userDO.getUsername());
        returnMsg.put("password",userDO.getIdcard().substring(userDO.getIdcard().length()-6,userDO.getIdcard().length()));
        result.put("response", ConstantUtils.SUCCESS);
        result.put("msg", returnMsg);
        return result;
    }

    /**
     * 修改用户
     *
     * @param jsonData
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject updateUser(String jsonData) {
        JSONObject result = new JSONObject();
        if (StringUtils.isEmpty(jsonData)) {
            result.put("msg", "parameter jsonData is null");
            result.put("response", ConstantUtils.FAIL);
            return result;
        }
        JSONObject jsonObject = JSONObject.parseObject(jsonData);
        JSONObject user = jsonObject.getJSONObject("user");
        JSONArray org = jsonObject.getJSONArray("org");
        JSONArray area = jsonObject.getJSONArray("area");
        JSONArray equipment = jsonObject.getJSONArray("equipment");
       /* if (null == user ||  CollectionUtils.isEmpty(org) && !user.getString("saasId").equalsIgnoreCase(defaultSaasId)) {
            result.put("msg", "请点击机构管理选择所在机构");
            result.put("response", ConstantUtils.FAIL);
            return result;
        }*/
        //修改用户信息
        UserDO userDO = null;
        try {
            userDO = objectMapper.readValue(user.toJSONString(), UserDO.class);
            UserDO oldUser = userDao.findOne(userDO.getId());
            userDO.setPassword(oldUser.getPassword());
            userDO.setUpdateTime(new Date());
        } catch (IOException e) {
            result.put("msg", "convert user jsonObject to UserDO failed," + e.getCause());
            result.put("response", ConstantUtils.FAIL);
            return result;
        }
        this.save(userDO);

        if (!CollectionUtils.isEmpty(org)) {
            //修改用户机构关联关系
            Set<Object> roleIdList = baseOrgUserService.findIdListByUserId(userDO.getId());
            BaseOrgUserDO orgUserDO = null;
            try {
                for (Object obj : org) {
                    orgUserDO = objectMapper.readValue(obj.toString(), BaseOrgUserDO.class);
                    orgUserDO.setUserId(userDO.getId());
                    if (roleIdList.contains(orgUserDO.getId())) {
                        roleIdList.remove(orgUserDO.getId());
                    }
                    baseOrgUserService.save(orgUserDO);
                }
            } catch (IOException e) {
                result.put("msg", "convert org jsonObject to BaseOrgUserDO failed," + e.getCause());
                result.put("response", ConstantUtils.FAIL);
                return result;
            }
            // 表示没有删除，只有修改
            if (roleIdList.size() > 0) {
                baseOrgUserService.delete(roleIdList.toArray());
            }
        }

        //area:[{"city":"","cityName":"","town":"","townName":"","hospital":"","hospitalName":""}]
        //用户所属区域添加
        if (area!=null&&area.size()!=0){
            userAreaDao.deleteByUserId(userDO.getId());
            for (int i=0;i<area.size();i++){
                JSONObject object = area.getJSONObject(i);
                WlyyUserAreaDO userAreaDO = new WlyyUserAreaDO();
                userAreaDO.setUserId(userDO.getId());
                userAreaDO.setCity(object.getString("city"));
                userAreaDO.setCityName(object.getString("cityName"));
                userAreaDO.setTown(object.getString("town"));
                userAreaDO.setTownName(object.getString("townName"));
                if (!StringUtils.isEmpty(object.getString("hospital"))){
                    userAreaDO.setHospital(object.getString("hospital"));
                    userAreaDO.setHospitalName(object.getString("hospitalName"));
                }
                userAreaDO.setCreateTime(new Date());
                userAreaDO.setUpdateTime(new Date());
                userAreaDO.setDel(1);
                userAreaDao.save(userAreaDO);
            }
        }
        //用户所管设备添加
        //equipment:[{"equipmentId":"","equipmentName":""}]
        if (equipment!=null&&equipment.size()!=0){
            userEquipmentDao.deleteByUserId(userDO.getId());
            for (int i=0;i<equipment.size();i++){
                JSONObject object = equipment.getJSONObject(i);
                WlyyUserEquipmentDO userEquipmentDO = new WlyyUserEquipmentDO();
                userEquipmentDO.setDel(1);
                userEquipmentDO.setUserId(userDO.getId());
                userEquipmentDO.setCity(object.getString("city"));
                userEquipmentDO.setCityName(object.getString("cityName"));
                userEquipmentDO.setTown(object.getString("town"));
                userEquipmentDO.setTownName(object.getString("townName"));
                if (!StringUtils.isEmpty(object.getString("hospital"))){
                    userEquipmentDO.setHospital(object.getString("hospital"));
                    userEquipmentDO.setHospitalName(object.getString("hospitalName"));
                }
                userEquipmentDO.setEquipmentId(object.getString("equipmentId"));
                userEquipmentDO.setEquipmentName(object.getString("equipmentName"));
                userEquipmentDO.setCreateTime(new Date());
                userEquipmentDO.setUpdateTime(new Date());
                userEquipmentDao.save(userEquipmentDO);
            }
        }

        result.put("response", ConstantUtils.SUCCESS);
        result.put("msg", userDO);
        return result;
    }

    /**
     * 获取单个用户信息
     * @param userId 用户id
     * @return
     */
    public JSONObject getOneUserInfo(String userId) throws Exception{
        JSONObject result = new JSONObject();
        if(StringUtils.isEmpty(userId)){
            result.put("msg","parameter userId is null ");
            result.put("response",ConstantUtils.FAIL);
            return result;
        }

        //用户基本信息
        UserDO user = userDao.findOne(userId);
        if(null == user){
            result.put("msg","User not exist for id:" + userId);
            result.put("response",ConstantUtils.FAIL);
            return result;
        }
        //用户角色
        RoleDO roleDO = roleDao.findOne(user.getRoleId());

        //用户所属区域
        List<WlyyUserAreaDO> userAreaDOList = userAreaDao.findAllByUserId(userId);

        //用户管理的设备
        List<WlyyUserEquipmentDO> userEquipmentDOList = userEquipmentDao.findAllByUserId(userId);

        //用户关联的机构
        List<BaseOrgUserDO>  orgList = baseOrgUserService.findAllByUserId(user.getId());
        JSONObject userInfo = new JSONObject();
        userInfo.put("user",user);
        userInfo.put("role",roleDO);
        userInfo.put("userArea",userAreaDOList);
        userInfo.put("userEquipment",userEquipmentDOList);
        userInfo.put("org",orgList);
        result.put("response",ConstantUtils.SUCCESS);
        result.put("msg",userInfo);
        return result;
    }

    /**
     * 租户只能给用户归属到自己租户底下的机构
     * 机构管理员只能属于一个租户
     * @param saasid
     * @param userId
     * @return
     */
    public JSONObject generateUserOrgTree(String saasid,String userId,String roleId) throws IOException {
        JSONObject result = new JSONObject();
        List<OrgTree> orgList = new ArrayList<>();
        // 有归属租户加载saas底下的所有机构树列表，角色为机构管理员时不需要选管理机构
        String admin ="admin";
        if(!StringUtils.isEmpty(saasid) && !StringUtils.endsWithIgnoreCase(admin,roleId)){
            StringBuilder sql = new StringBuilder("SELECT " +
                    "  tree.* " +
                    " FROM " +
                    "  org_tree tree, " +
                    "  base_org org, " +
                    "  base_org_saas saas " +
                    " WHERE " +
                    "  org.code = saas.org_code " +
                    " and  saas.saasid = '{saasid}' " +
                    " and  (tree.code = org.code or tree.code = org.province_code or tree.code = org.city_code or tree.code = town_code) " +
                    " ORDER BY tree.name;");
            orgList = jdbcTemplate.query(sql.toString().replace("{saasid}",saasid),new BeanPropertyRowMapper(OrgTree.class));
        }
        if(!StringUtils.isEmpty(userId)){// 用户不为空表示修改，需要筛选出用户已经选择过的机构，设置checked为true
            Set<String> codeSet = baseOrgUserService.findorgCodeListByUserId(userId);
            orgList.forEach( one -> {
                if(codeSet.contains(one.getCode())){
                    one.setChecked(true);
                }
            });
          /*  StringBuilder sql = new StringBuilder("SELECT tree.* " +
                    "FROM " +
                    "  org_tree tree, " +
                    "  base_org org, " +
                    "  base_org_user user " +
                    "WHERE " +
                    "  org.code = user.org_code " +
                    "  AND user.user_id = '{userId}' " +
                    "  and (tree.code = org.code OR tree.code = org.province_code OR tree.code = org.city_code OR tree.code = town_code) " +
                    "ORDER BY tree.name;");
            orgList = jdbcTemplate.query(sql.toString().replace("{userId}",userId),new BeanPropertyRowMapper(OrgTree.class));*/
        }

        if(!CollectionUtils.isEmpty(orgList)){
            String tree = orgTreeService.makeTree(orgList,false,true);
            result.put("msg",objectMapper.readValue(tree,JSONArray.class));
        }else{
            result.put("msg",orgList);
        }
        result.put("response", ConstantUtils.SUCCESS);
        return result;
    }

    /**
     * 租户只能给用户归属到自己租户底下的机构
     * 机构管理员只能属于一个租户，增加社区树
     * @param saasid
     * @param userId
     * @return
     */
    public JSONObject orgChoiceInfo(String saasid,String userId,String roleId) throws IOException {
        JSONObject result = new JSONObject();
        List<OrgTree> orgList = new ArrayList<>();
        String admin = "admin";
        // 有归属租户加载saas底下的所有机构树列表，角色为机构管理员时不需要选管理机构
        if(!StringUtils.isEmpty(saasid) && !StringUtils.endsWithIgnoreCase(admin,roleId)){
            StringBuilder sql = new StringBuilder("SELECT tree.*  FROM org_tree tree, base_org org, base_org_saas saas WHERE org.code = saas.org_code and 'null'= '{saasid}';");
 //           StringBuilder sql = new StringBuilder("SELECT tree.* FROM base_org base , org_tree tree WHERE base.`code` = tree.code ");
            orgList = jdbcTemplate.query(sql.toString().replace("{saasid}","null"),new BeanPropertyRowMapper(OrgTree.class));
        }
        if(!StringUtils.isEmpty(userId)){// 用户不为空表示修改，需要筛选出用户已经选择过的机构，设置checked为true
            Set<String> codeSet = baseOrgUserService.findorgCodeListByUserId(userId);
            orgList.forEach( one -> {
                if(codeSet.contains(one.getCode())){
                    one.setChecked(true);
                }
            });
        }

        if(!CollectionUtils.isEmpty(orgList)){
            String tree = orgTreeService.makeTree(orgList,false,true);
            result.put("msg",objectMapper.readValue(tree,JSONArray.class));
        }else{
            result.put("msg",orgList);
        }
        result.put("response", ConstantUtils.SUCCESS);
        return result;
    }


    /**
     * 用户修改密码
     * @param userId
     * @return
     */
    public JSONObject updatePwd(String userId,String pwd,String oldpwd){
        JSONObject result = new JSONObject();
        UserDO user = userDao.findOne(userId);
        if(null == user){
            result.put("response", ConstantUtils.FAIL);
            result.put("msg","user not exist for id : " + userId);
            return result;
        }
    
        String orgPwMd5 = MD5.md5Hex(oldpwd + "{" + user.getSalt() + "}");
        if(!orgPwMd5.equals(user.getPassword())){
            result.put("response", ConstantUtils.FAIL);
            result.put("msg","旧密码不正确！");
            return result;
        }

        if(StringUtils.isEmpty(pwd)){
            result.put("response", ConstantUtils.FAIL);
            result.put("msg","新密码不能为空！");
            return result;
        }

        user.setSalt(randomString(5));
        user.setEnabled(true);
        user.setLocked(false);
        user.setLoginFailureCount(0);
        user.setPassword(MD5.md5Hex(pwd + "{" + user.getSalt() + "}"));
        userDao.save(user);

        result.put("response",ConstantUtils.SUCCESS);
        result.put("msg", "修改成功");
    
        //设置用户密码过期时间
        saveUserPwlimitDate(userId);
        
        return result;
    }
    
    public boolean saveUserPwlimitDate(String user){
        String key = "base:authPw:user:" + user;
        com.alibaba.fastjson.JSONObject valueJson = new com.alibaba.fastjson.JSONObject();
        valueJson.put("updateTime",new Date().getTime());
        valueJson.put("isChanged",true);
        redisTemplate.opsForValue().set(key,valueJson.toJSONString());
        return true;
    }
    
    /**
     * 用户重置密码
     * @param userId
     * @return
     */
    public JSONObject resetPassword(String userId){
        JSONObject result = new JSONObject();
        UserDO user = userDao.findOne(userId);
        if(null == user){
            result.put("response", ConstantUtils.FAIL);
            result.put("msg","user not exist for id : " + userId);
            return result;
        }
//        registerWithIdcard(user);
        String idcard = user.getIdcard();
        String mobile = user.getMobile();
        String password = null;
        
        if(!StringUtils.isEmpty(password)&&idcard.length()>10){
            password = idcard.substring(idcard.length()-6,idcard.length());
        }else if(!StringUtils.isEmpty(mobile)&&mobile.length()>=11){
            password = mobile.substring(mobile.length()-6,mobile.length());
        }
        
        if(StringUtils.isEmpty(password)){
            result.put("response", ConstantUtils.FAIL);
            result.put("msg","idcard or moblie not exist : " + userId);
            return result;
        }
        
        user.setSalt(randomString(5));
        user.setEnabled(true);
        user.setLocked(false);
        user.setLoginFailureCount(0);
        user.setPassword(MD5.md5Hex(password + "{" + user.getSalt() + "}"));
        userDao.save(user);
        
        result.put("response",ConstantUtils.SUCCESS);
        result.put("msg", password);
        return result;
    }


    /**
     * 判断用户账号是否存在
     * @param code
     * @return
     */
    public Boolean existUsername(String code){
        if(StringUtils.isEmpty(code)) {
            return null;
        }
        return userDao.existsByUsername(code);
    }


    /**
     * 生效或失效单个用户
     * @param userId
     * @param lock
     * @return
     */
    public JSONObject lockOrUnlocakUser(String userId,boolean lock){
        JSONObject result = new JSONObject();
        if(StringUtils.isEmpty(userId) || StringUtils.isEmpty(lock)){
            result.put("msg","parameter id or del is null");
            result.put("response",ConstantUtils.FAIL);
            return result;
        }
        UserDO user = userDao.findOne(userId);
        if( null == user ){
            result.put("msg","user not exist for id:" + userId);
            result.put("response",ConstantUtils.FAIL);
            return result;
        }
        user.setLocked(lock);
        user.setLockedDate(new Date());
        this.save(user);
        result.put("response",ConstantUtils.SUCCESS);
        return result;
    }


    /**
     * 生效或失效单个用户
     * @param userId
     * @param lock
     * @return
     */
    public JSONObject enableOrDisable(String userId,boolean lock){
        JSONObject result = new JSONObject();
        if(StringUtils.isEmpty(userId) || StringUtils.isEmpty(lock)){
            result.put("msg","parameter id or del is null");
            result.put("response",ConstantUtils.FAIL);
            return result;
        }
        UserDO user = userDao.findOne(userId);
        if( null == user ){
            result.put("msg","user not exist for id:" + userId);
            result.put("response",ConstantUtils.FAIL);
            return result;
        }
        user.setEnabled(lock);
        this.save(user);
        result.put("response",ConstantUtils.SUCCESS);
        return result;
    }

    /**
     * 用户信息列表
     * @param name
     * @param saasid
     * @param roleId
     * @param page
     * @param size
     * @return
     * @throws Exception
     */
    public JSONObject userInfoList(String name,String saasid,String roleId,int page,int size,String wechatId) throws Exception {
        JSONObject result = new JSONObject();
   /*     int start = 0 == page ? page++ : (page - 1) * size;
        int end = 0 == size ? 15 : page * size;*/
        String realName = null == name ? "" : name;
        String saasidValue = null == saasid ? "" : saasid;
        String roleIdValue = null == roleId ? "" : roleId;

//        String sql = "SELECT " +
//                "  usr.id as \"id\", " +
//                "  usr.name as \"realName\", " +
//                "  usr.username as \"username\", " +
//                "  case when usr.enabled=0 then '已失效' when usr.enabled=1 then '生效中' end  as \"enabled\", " +
//                "  usr.mobile as \"mobile\", " +
//                "  saas.name as \"saasName\", " +
//                "  role.name as \"roleName\" " +
//                " FROM " +
//                "  base_user usr, " +
//                "  base_saas saas, " +
//                "  base_role role " +
//                " WHERE " +
//                "  usr.saas_id = saas.id " +
//                "  AND " +
//                "  usr.role_id = role.id " +
//                " and (usr.name like '{realName}' or '' ='{realName}') " +
//                "  and (saas.id = '{saasid}' or '' = '{saasid}') " +
//                "  and ( usr.role_id = '{roleId}' or '' = '{roleId}') " +
//                " ORDER BY usr.create_time DESC";
//        String finalSql = sql
//                .replace("{realName}","%" + realName + "%")
//                .replace("{saasid}",saasidValue)
//                .replace("{roleId}",roleIdValue);
//
//        String countSql = "SELECT " +
//                "  count(usr.id) " +
//                "FROM " +
//                "  base_user usr, " +
//                "  base_saas saas, " +
//                "  base_role role " +
//                "WHERE " +
//                "  usr.saas_id = saas.id " +
//                "  AND " +
//                "  usr.role_id = role.id " +
//                " and (usr.name like '{realName}' or '' ='{realName}') " +
//                "  and (saas.id = '{saasid}' or '' = '{saasid}') " +
//                "  and ( usr.role_id = '{roleId}' or '' = '{roleId}') ";
//        String finalCountSql = countSql
//                .replace("{realName}", "%" + realName + "%")
//                .replace("{saasid}",  saasidValue )
//                .replace("{roleId}",  roleIdValue );
//        Logger.getAnonymousLogger().info("sql="+sql);
//        List<Map<String, Object>> list = hibenateUtils.createSQLQuery(finalSql,page,size);
//        Integer count = jdbcTemplate.queryForObject(finalCountSql, Integer.class);
//        result.put("count", count);
//        result.put("msg", JavaBeanUtils.getInstance().mapListJson(list));


        String finalSql="SELECT\n" +
                "\t\t\tusr . ID AS \"id\",\n" +
                "\t\t\tusr . NAME AS \"realName\",\n" +
                "\t\t\tusr .username AS \"username\",\n" +
                "\t\t\tCASE \n" +
                "\t\tWHEN usr .enabled=0 THEN\n" +
                "\t\t\t'已失效'\n" +
                "\t\tWHEN usr .enabled=1 THEN\n" +
                "\t\t\t'生效中'\n" +
                "\t\tEND  AS \"enabled\",\n" +
                "\t\tusr .mobile AS \"mobile\",\n" +
                "\t\tsaas. NAME AS \"saasName\",\n" +
                "\t\tROLE . NAME AS \"roleName\"\n" +
                "\tFROM\n" +
                "\t\tbase_user usr,\n" +
                "\t\tbase_saas saas,\n" +
                "\t\tbase_role ROLE\n" +
                "\tWHERE\n" +
                "\t\tusr .saas_id = saas. ID\n" +
                "\tAND usr .role_id = ROLE . ID\n" ;
                if(!realName.equals(null) && !realName.equals("")){
                    finalSql = finalSql + " and usr . NAME LIKE '%"+realName+"%'";
                }
                if(!saasidValue.equals(null) && !saasidValue.equals("")){
                    finalSql = finalSql + " and saas. id = '"+saasidValue+"'";
                }
                if(!roleIdValue.equals(null) && !roleIdValue.equals("")){
                    finalSql = finalSql + " and usr .role_id = '"+roleIdValue+"'";
                }
                finalSql = finalSql + " ORDER BY usr .create_time DESC";
        Logger.getAnonymousLogger().info("finalSql="+finalSql);
        String sql = finalSql
                .replace("{realName}","%" + realName + "%")
                .replace("{saasid}",saasidValue)
                .replace("{roleId}",roleIdValue);

        List<Map<String, Object>> list=null;
        if ("xm_ykyy_wx".equalsIgnoreCase(wechatId)){

            if (flag){
                sql+=" LIMIT  " + (page - 1) * size + "," + size + "";
                Logger.getAnonymousLogger().info("sql="+sql);
                list = jdbcTemplate.queryForList(sql);
            }else {
                String oracleSql="SELECT\n" +
                        "\t*\n" +
                        "FROM\n" +
                        "\t(\n" +
                        "\t\tSELECT\n" +
                        "\t\t\tA .*\n" +
                        "\t\tFROM\n" +
                        "\t\t\t(";

                oracleSql+=sql;

                oracleSql+="\t\t\t) A\n" +
                        "\t\tWHERE\n" +
                        "  ROWNUM <="+page*size +
                        "\t) \n" +
                        "WHERE\n" +
                        "\tROWNUM >= "+(page-1)*size;
                Logger.getAnonymousLogger().info("oracleSql="+oracleSql);
                list = jdbcTemplate.queryForList(oracleSql);
            }

        }else {
            sql+=" LIMIT  " + (page - 1) * size + "," + size + "";
            Logger.getAnonymousLogger().info("sql="+sql);
            list = jdbcTemplate.queryForList(sql);
        }


        String countSql = "SELECT " +
                "  COUNT(usr.id) " +
                "FROM " +
                "  base_user usr, " +
                "  base_saas saas, " +
                "  base_role role " +
                "WHERE " +
                "  usr.saas_id = saas.id " +
                "  AND " +
                "  usr.role_id = role.id " ;
                if(!realName.equals(null) && !realName.equals("")){
                    countSql = countSql + " and usr . NAME LIKE '%"+realName+"%'";
                }
                if(!saasidValue.equals(null) && !saasidValue.equals("")){
                    countSql = countSql + " and saas. id = '"+saasidValue+"'";
                }
                if(!roleIdValue.equals(null) && !roleIdValue.equals("")){
                    countSql = countSql + " and usr .role_id = '"+roleIdValue+"'";
                }
        Logger.getAnonymousLogger().info("countSql="+countSql);
        String finalCountSql = countSql
                .replace("{realName}", "%" + realName + "%")
                .replace("{saasid}",  saasidValue )
                .replace("{roleId}",  roleIdValue );
        Logger.getAnonymousLogger().info("finalCountSql="+finalCountSql);
        Integer count = jdbcTemplate.queryForObject(finalCountSql, Integer.class);
        result.put("count", count);
        result.put("msg", JavaBeanUtils.getInstance().mapListJson(list));
        return result;
    }

}
