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

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.jw.base.dao.org.BaseOrgUserDao;
import com.yihu.jw.base.service.org.tree.SimpleTree;
import com.yihu.jw.base.service.org.tree.SimpleTreeNode;
import com.yihu.jw.base.service.org.tree.TreeNode;
import com.yihu.jw.base.service.user.UserService;
import com.yihu.jw.base.util.ConstantUtils;
import com.yihu.jw.base.util.JavaBeanUtils;
import com.yihu.jw.entity.base.org.BaseOrgDO;
import com.yihu.jw.entity.base.org.BaseOrgSaasDO;
import com.yihu.jw.entity.base.org.BaseOrgUserDO;
import com.yihu.jw.entity.base.user.UserDO;
import com.yihu.jw.entity.hospital.consult.WlyyHospitalSysDictDO;
import com.yihu.jw.hospital.dict.WlyyHospitalSysDictDao;
import com.yihu.jw.org.dao.BaseOrgDao;
import com.yihu.jw.utils.StringUtil;
import com.yihu.jw.utils.hibernate.HibenateUtils;
import com.yihu.mysql.query.BaseJpaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

/**
 * 
 * 机构信息服务service
 * 
 * @version 
 * <pre>
 * Author	Version		Date		Changes
 * litaohong    1.0  2018年08月31日 Created
 *
 * </pre>
 * @since 1.
 */
@Service
public class BaseOrgService extends BaseJpaService<BaseOrgDO, BaseOrgDao> {

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

    @Autowired
    private BaseOrgDao baseOrgDao;

    @Autowired
    private BaseOrgSaasService baseOrgSaasService;

    @Autowired
    private OrgTreeService orgTreeService;

    @Autowired
    private UserService userService;

    @Autowired
    private  BaseOrgUserService baseOrgUserService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private HibenateUtils hibenateUtils;
    @Autowired
    private BaseOrgUserDao  baseOrgUserDao;
    @Autowired
    private WlyyHospitalSysDictDao hospitalSysDictDao;

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

    /**
     * 机构基础信息列表
     * @param codeOrName
     * @param orgStatus
     * @return
     */
    public JSONObject queryOrgBaseInfoList(String codeOrName,String orgStatus,String orgType,int page,int size,String wechatId,String userId) throws Exception {
        JSONObject result = new JSONObject();
        int start = 0 == page ? page++ : (page - 1) * size;
        int end = 0 == size ? 15 : page * size;
        String filters = "";
        if(!StringUtil.isBlank(userId)){
           //判断当前用户是否不需要过滤测试机构
            List<WlyyHospitalSysDictDO>  dictDOs = hospitalSysDictDao.findByDictNameAndDictCode("jkzl_user",userId);
            if(dictDOs.size()==0){
                //需要过滤
                String sql = "SELECT GROUP_CONCAT(dict_code) orgCodes from wlyy_hospital_sys_dict WHERE dict_name = 'jkzl_org' ";
                List<Map<String,Object>> list =  jdbcTemplate.queryForList(sql);
                if(list.size()>0){
                    String orgCodes = String.valueOf(list.get(0).get("orgCodes"));
                    orgCodes = orgCodes.replaceAll(",","','");
                    filters = " and code not in ('"+orgCodes+"')";
                }
            }

        }
        String codeOrNameValue = null == codeOrName ? "" : codeOrName;
                String sql = "SELECT\n" +
                        "\tID AS \"id\",\n" +
                        "\tcode AS \"code\",\n" +
                        "\tNAME AS \"name\",\n" +
                        "\tCASE \n" +
                        "WHEN del=1 THEN\n" +
                        "\t'有效'\n" +
                        "WHEN del=0 THEN\n" +
                        "\t'失效'\n" +
                        "ELSE\n" +
                        "\t'失效'\n" +
                        "END AS \"del\",\n" +
                        " province_name AS \"provinceName\"," +
                        " city_name AS \"cityName\" ," +
                        "town_name AS \"townName\"," +
                        " photo AS \"photo\"," +
                        " brief AS \"brief\"," +
                        "address AS \"address\"\n" +
                        "FROM\n" +
                        "\tbase_org\n" +
                        "WHERE\n" +
                        " 1=1 ";
                if (!StringUtil.isBlank(codeOrNameValue)){
                    sql+=" and (code like '%"+codeOrNameValue+"%' or  NAME like '%"+codeOrNameValue+"%') ";
                }
                if (!StringUtil.isBlank(orgStatus)){
                    sql+=" and del = '"+orgStatus+"'";
                }
                if (!StringUtil.isBlank(orgType)){
                    sql+=" and type = '"+orgType+"'";
                }
                if(!StringUtil.isBlank(filters)){
                    sql+= filters;
                }
                sql+="  ORDER BY\n" +
                        "\tcreate_time DESC";
                String finalSql = sql;
        List<Map<String, Object>> list=null;

        if ("xm_ykyy_wx".equalsIgnoreCase(wechatId)){
            if (flag){
                finalSql+=" LIMIT  " + (page - 1) * size + "," + size + "";
                list = jdbcTemplate.queryForList(finalSql);
            }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+=finalSql;

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


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

        String countSql = "SELECT count(id)" +
                " FROM base_org " +
                " WHERE " +
               " 1=1 ";
        if (!StringUtil.isBlank(codeOrNameValue)){
            countSql+=" and (code like '%"+codeOrNameValue+"%' or  NAME like '%"+codeOrNameValue+"%') ";
        }
        if (!StringUtil.isBlank(orgStatus)){
            countSql+=" and del = '"+orgStatus+"'";
        }
        if(!StringUtil.isBlank(filters)){
            countSql+= filters;
        }
        Logger.getAnonymousLogger().info("finalCountSql="+countSql);
        Integer count = jdbcTemplate.queryForObject(countSql, Integer.class);
        result.put("count", count);
        result.put("msg", JavaBeanUtils.getInstance().mapListJson(list));
        return result;
    }

    /**
     * 根据id查询机构，只查询机构的信息
     * @param id
     * @return
     */
    public JSONObject queryOneById(String id) throws JsonProcessingException {
        JSONObject result = new JSONObject();
        if(StringUtils.isEmpty(id)){
            result.put("msg","该机构不存在 id:"+id);
            result.put("response",ConstantUtils.FAIL);
            return result;
        }
        BaseOrgDO baseOrgDO = baseOrgDao.findOne(id);
        if(null == baseOrgDO){
            return null;
        }
        /*BaseOrgUserDO baseOrgUserDO=baseOrgUserDao.getBaseOrgUserByOrgCodeAndUserid(baseOrgDO.getCode(),baseOrgDO.getOrgAdmin());
        baseOrgDO.setBaseOrgUserDO(baseOrgUserDO);*/
        result.put("response",ConstantUtils.SUCCESS);
        result.put("msg",baseOrgDO);
        return result;
    }

    /**
     * 新增/修改机构
     * @param baseOrgDO
     * @param orgAdminJson
     */
//    @Transactional(rollbackFor = Exception.class)
    public String createOrUpdateOrg(BaseOrgDO baseOrgDO,JSONObject orgAdminJson){
        UserDO userDO = null;
        //id为空表示新增
        if(StringUtils.isEmpty(baseOrgDO.getId())){
            String mobile = orgAdminJson.getString("mobile");
            String adminName = orgAdminJson.getString("orgAdmin");
            if(StringUtils.isEmpty(mobile)){
                return "联系电话不能为空！";
            }
            if(mobile.length()!=11){
                return "联系电话格式错误！";
            }
            baseOrgDO.setOrgAdmin(adminName);
            baseOrgDO.setAdminMobile(mobile);
            baseOrgDao.save(baseOrgDO);

            //新增机构与saas关联关系，初始saas设置为默认值，机构分配给租户在租户管理中操作
            BaseOrgSaasDO baseOrgSaasDO = new BaseOrgSaasDO();
            baseOrgSaasDO.setOrgCode(baseOrgDO.getCode());
            baseOrgSaasDO.setSaasid(defaultSaasId);
            baseOrgSaasService.save(baseOrgSaasDO);

            // 新增机构与管理员关联关系
            BaseOrgUserDO baseOrgUserDO = new BaseOrgUserDO();
            baseOrgUserDO.setOrgCode(baseOrgDO.getCode());
            baseOrgUserDO.setUserId(mobile);
            baseOrgUserService.save(baseOrgUserDO);

            // 新增用户（管理员）
            userDO = new UserDO();
            userDO.setUsername(mobile);
            userDO.setName(adminName);
            userDO.setMobile(mobile);
            // 默认为机构管理员，系统初始化时会在base_role表中初始化三类角色数据，1-超级管理员，2-租户管理员，3-机构管理员
            userDO.setRoleId("3");
            userService.registerWithMobile(userDO);

            //新增机构与区域的树形结构关系
            orgTreeService.addOrgTreeNode(baseOrgDO);
        }else{
            BaseOrgDO oldBaseOrgDO = baseOrgDao.findOne(baseOrgDO.getId());
            if(null == oldBaseOrgDO){
                return "机构不存在";
            }
            if(!baseOrgDO.getCode().equalsIgnoreCase(oldBaseOrgDO.getCode()) || !baseOrgDO.getName().equalsIgnoreCase(oldBaseOrgDO.getName())){
                orgTreeService.updateOrgTreeNode(oldBaseOrgDO,baseOrgDO,OrgTree.Level.org.getLevelValue());
            }
            if(!baseOrgDO.getTownCode().equalsIgnoreCase(oldBaseOrgDO.getTownCode())){
                orgTreeService.updateOrgTreeNode(oldBaseOrgDO,baseOrgDO,OrgTree.Level.town.getLevelValue());
            }
            if(!baseOrgDO.getCityCode().equalsIgnoreCase(oldBaseOrgDO.getCityCode())){
                orgTreeService.updateOrgTreeNode(oldBaseOrgDO,baseOrgDO,OrgTree.Level.city.getLevelValue());
            }
            if(!baseOrgDO.getProvinceCode().equalsIgnoreCase(oldBaseOrgDO.getProvinceCode())){
                orgTreeService.updateOrgTreeNode(oldBaseOrgDO,baseOrgDO,OrgTree.Level.province.getLevelValue());
            }
            baseOrgDao.save(baseOrgDO);
        }
        return ConstantUtils.SUCCESS;
    }

    /**
     * 判断机构代码是否存在
     * @param code
     * @return
     */
    public Boolean existCode(String code){
        if(StringUtils.isEmpty(code)) {
            return null;
        }
        return baseOrgDao.existsByCode(code);
    }

    /**
     * 生效或失效单个机构
     * @param id
     * @param del
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public String enableOrDisableOrg(String id,String del){
        JSONObject result = new JSONObject();
        if(StringUtils.isEmpty(id) || StringUtils.isEmpty(del)){
            result.put("msg","参数id or del 为空");
            result.put("response",ConstantUtils.FAIL);
            return result.toJSONString();
        }
        BaseOrgDO baseOrgDO = baseOrgDao.findOne(id);
        if( null == baseOrgDO ){
            result.put("msg","该机构不存在 id:" + id);
            result.put("response",ConstantUtils.FAIL);
            return result.toJSONString();
        }

        baseOrgDO.setDel(del);
        this.save(baseOrgDO);
        // 将机构状态改为失效
        if(StringUtils.endsWithIgnoreCase(ConstantUtils.STATUS_0,del)){
            // 将机构关联的树形结构表中的机构数据删除
            orgTreeService.deleteByCode(baseOrgDO);
        }else if(StringUtils.endsWithIgnoreCase(ConstantUtils.STATUS_1,del)){
            // 将机构关联的树形结构表中的机构数据恢复
            orgTreeService.addOrgTreeNode(baseOrgDO);
        }

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

    /**
     * 构建机构区域树形结构
     * @return
     */
    public String getOrgAreaTree(){

        List<TreeNode> treeNodes = new ArrayList<>();
        treeNodes.addAll(orgTreeService.findListByLevel(OrgTree.Level.org.getLevelValue()));
        SimpleTree tree = new SimpleTree(treeNodes,"");
        List<SimpleTreeNode> treeNode = tree.getRoot();
        SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
        filter.getExcludes().add("parent");
        filter.getExcludes().add("allChildren");
//        filter.getExcludes().add("parentNodeId");
        filter.getExcludes().add("orderNum");
        filter.getExcludes().add("level");

        return JSONObject.toJSONString(treeNode, filter);
    }

    public String getOrgAreaTree(String saasId){
        StringBuffer sql = new StringBuffer("SELECT t.id as \"id\"," +
                "t.PARENT_CODE as \"PARENT_CODE\"," +
                "t.CODE as\"CODE\"," +
                "t.NAME as \"NAME\"," +
                "t.ORG_LEVEL as \"ORG_LEVEL \" from base_org b,org_tree t,base_org_saas o ")
                .append("WHERE o.saasid='").append(saasId).append("' AND o.org_code = b.code AND ")
                .append("(b.code= t.code or b.city_code=t.code or b.province_code = t.code or b.town_code=t.code)");

        List<TreeNode> treeNodes = new ArrayList<>();
        treeNodes.addAll(jdbcTemplate.query(sql.toString(),new BeanPropertyRowMapper(OrgTree.class)));
        SimpleTree tree = new SimpleTree(treeNodes,"");
        List<SimpleTreeNode> treeNode = tree.getRoot();
        SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
        filter.getExcludes().add("parent");
        filter.getExcludes().add("allChildren");
//        filter.getExcludes().add("parentNodeId");
        filter.getExcludes().add("orderNum");
        filter.getExcludes().add("level");

        return JSONObject.toJSONString(treeNode, filter);
    }

    /**
     * 查找某一saasId下的有效的机构code
     * @param saasId
     * @return
     */
    public List findOrgCodeListBySaasId(String saasId){
        List result = new ArrayList();
        /*if(StringUtils.isEmpty(saasId)){
            return result;
        }*/
        return baseOrgDao.findOrgCodeBySaasId(saasId);
    }

     /**
     * 查找某一saasId下的有效的机构列表，新增团队时选择归属机构时用到
     * @param saasId
     * @return
     */
    public List findOrgListBySaasId(String saasId){
//        List result = new ArrayList();
//        if(StringUtils.isEmpty(saasId)){
//            return result;
//        }
        return baseOrgDao.findOrgListBySaasId();
    }


}
