package com.yihu.jw.utils.hibernate;

import com.yihu.jw.entity.hospital.prescription.HlwCf01DO;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.transform.Transformers;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.ParameterMode;
import javax.persistence.PersistenceContext;
import javax.persistence.StoredProcedureQuery;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 数据库查询工具，mysql与Oracle 通用复诊查询
 * 支持原生SQL。联表，动态传参。分页查询
 * 不支持数据库特有的函数
 * <p>
 * Created by Trick on 2019/12/10.
 */
@Component
@Transactional
public class HibenateUtils {
    /**
     * JPA 数据源
     */
    @PersistenceContext
    private EntityManager entityManager;

    /**
     * 创建SQL查询，根据配置，获取数据库方言
     * sql为原生sql语句，查询，Oracle不区分大小写，返回值需要驼峰命名，字段别名需要加 双引号
     * 目前只支持通用的聚合函数，特有的聚合函数不支持
     *
     * @param sql
     * @param page 第几页，1开始
     * @param size 每页记录数
     * @return
     */
    public List<Map<String, Object>> createSQLQuery(String sql, Integer page, Integer size) {
        Session session = (Session) entityManager.getDelegate();

        SQLQuery query = session.createSQLQuery(sql);
        query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        if(page!=null&&size!=null){
            query.setFirstResult((page - 1) * size);
            query.setMaxResults(size);
        }
        List<Map<String, Object>> list = query.list();
        return list;
    }

    /**
     * 创建SQL查询，根据配置，获取数据库方言
     * sql为原生sql语句，查询，Oracle不区分大小写，返回值需要驼峰命名，字段别名需要加 双引号
     * 目前只支持通用的聚合函数，特有的聚合函数不支持
     * 无分页
     * @param sql
     * @return
     */
    public List<Map<String, Object>> createSQLQuery(String sql) {
        Session session = (Session) entityManager.getDelegate();
        SQLQuery query = session.createSQLQuery(sql);
        query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map<String, Object>> list = query.list();
        return list;
    }

    /**
     * 创建SQL查询，根据配置，获取数据库方言
     * sql为原生sql语句，查询，Oracle不区分大小写，返回值需要驼峰命名，字段别名需要加 双引号
     * 目前只支持通用的聚合函数，特有的聚合函数不支持
     * @param sql
     * @param params 动态占位符入参，例如 like:name
     * @param page 第几页，1开始
     * @param size 每页记录数
     * @return
     */
    public List<Map<String, Object>> createSQLQuery(String sql, Map<String, Object> params, Integer page, Integer size) {
        Session session = (Session) entityManager.getDelegate();
        SQLQuery query = session.createSQLQuery(sql);
        query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);

        //设置查询参数
        setSqlQueryByMap(query, params);

        if(page!=null&&size!=null){
            query.setFirstResult((page-1) * size);
            query.setMaxResults(size);
        }
        List<Map<String, Object>> list = query.list();
        return list;
    }


    /**
     * 创建SQL查询，根据配置，获取数据库方言
     * sql为原生sql语句，查询，Oracle不区分大小写，返回值需要驼峰命名，字段别名需要加 双引号
     * 目前只支持通用的聚合函数，特有的聚合函数不支持
     * @param sql
     * @param params 动态占位符入参，例如 like:name
     * @return
     */
    public List<Map<String, Object>> createSQLQuery(String sql, Map<String, Object> params) {
        Session session = (Session) entityManager.getDelegate();
        SQLQuery query = session.createSQLQuery(sql);
        query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);

        //设置查询参数
        setSqlQueryByMap(query, params);

        List<Map<String, Object>> list = query.list();
        return list;
    }

    /**
     * 设置查询参数
     * @param sqlQuery
     * @param params
     * @return
     */
    private SQLQuery setSqlQueryByMap(SQLQuery sqlQuery, Map<String, Object> params) {
        if (params != null && !params.isEmpty()) {
            for (String key : params.keySet()) {
                Object obj = params.get(key);
                if (obj instanceof Collection<?>) {
                    sqlQuery.setParameterList(key, (Collection<?>) obj);
                } else if (obj instanceof Object[]) {
                    sqlQuery.setParameterList(key, (Object[]) obj);
                } else {
                    sqlQuery.setParameter(key, obj);
                }
            }
        }
        return sqlQuery;
    }

    /**
     * 聚合函数类型装换
     * @param obj
     * @return
     */
    public Long objTransformLong(Object obj){
        //Oracle count(1) 聚合函数类型装换
        if(obj instanceof BigDecimal){
            return ((BigDecimal) obj).longValue();
        //Mysql count(1) 聚合函数类型装换
        }else if(obj instanceof BigInteger){
            return ((BigInteger)obj).longValue();
        }else{
            return 0L;
        }
    }

    public void updateBySql(String sql){
        Session session = (Session) entityManager.getDelegate();
        session.createSQLQuery(sql).executeUpdate();
    }


    public void save(Object object) {
        entityManager.persist(object);
    }

    /**
     * 更新
     * @param entity
     */
    public void update(Object entity){
        entityManager.merge(entity);
        entityManager.flush();
    }

    public void update(String id,Integer status){
        HlwCf01DO hlwCf01DO = entityManager.find(HlwCf01DO.class,id);
        hlwCf01DO.setFKZT(status);
        update(hlwCf01DO);
    }



    public String saveJdxx(String brxm,Date csny,Float brxb,String czgh,String sfzh,String sjhm,String ybkh,String lxdz,Float zy) {
        StoredProcedureQuery query = entityManager
                .createStoredProcedureQuery(" ZKSG.sp_zksg_jdkh_2021@xec_link") // 被调用存储过程名称
                .registerStoredProcedureParameter("P_BRXM", String.class, ParameterMode.IN) // 注册参数
                .registerStoredProcedureParameter("P_CSNY", Date.class, ParameterMode.IN)
                .registerStoredProcedureParameter("P_BRXB", Float.class, ParameterMode.IN)
                .registerStoredProcedureParameter("P_CZGH", String.class, ParameterMode.IN)
                .registerStoredProcedureParameter("P_SFZH", String.class, ParameterMode.IN)
                .registerStoredProcedureParameter("P_SJHM", String.class, ParameterMode.IN)
                .registerStoredProcedureParameter("P_YBKH", String.class, ParameterMode.IN)
                .registerStoredProcedureParameter("P_LXDZ", String.class, ParameterMode.IN)
                .registerStoredProcedureParameter("P_ZY", Float.class, ParameterMode.IN)
                .registerStoredProcedureParameter("P_ERRMSG", String.class, ParameterMode.INOUT)
                .setParameter("P_BRXM", brxm)
                .setParameter("P_CSNY", csny)
                .setParameter("P_CZGH", czgh)
                .setParameter("P_BRXB", brxb)
                .setParameter("P_SFZH",sfzh)
                .setParameter("P_SJHM",sjhm)
                .setParameter("P_YBKH",ybkh)
                .setParameter("P_LXDZ",lxdz)
                .setParameter("P_ZY",zy);
        query.execute();
        String priceStr = (String) query.getOutputParameterValue("P_ERRMSG"); // 获取存储过程中的返回值
        return priceStr;
    }


    public String updateJdxx(Float brid,String sfzh,String lxdz,Float zy,String lxdh) {
        StoredProcedureQuery query = entityManager
                .createStoredProcedureQuery("ZKSG.SP_ZKSG_MZBRXXXG@xec_link") // 被调用存储过程名称
                .registerStoredProcedureParameter("P_BRID", Float.class, ParameterMode.IN) // 注册参数
                .registerStoredProcedureParameter("P_SFZH", String.class, ParameterMode.IN)
                .registerStoredProcedureParameter("P_LXDZ", String.class, ParameterMode.IN)
                .registerStoredProcedureParameter("P_LXDH", String.class, ParameterMode.IN)
                .registerStoredProcedureParameter("P_ZY", Float.class, ParameterMode.IN)
                .registerStoredProcedureParameter("P_ERRMSG", String.class, ParameterMode.INOUT)
                .setParameter("P_BRID", brid)
                .setParameter("P_SFZH", sfzh)
                .setParameter("P_LXDZ", lxdz)
                .setParameter("P_LXDH", lxdh)
                .setParameter("P_ZY",zy);
        query.execute();
        String priceStr = (String) query.getOutputParameterValue("P_ERRMSG"); // 获取存储过程中的返回值
        return priceStr;
    }


    public String updateJzkh(Float brid,String ybkh) {
        StoredProcedureQuery query = entityManager
                .createStoredProcedureQuery("zksg.sp_zksg_jzkhxg@xec_link") // 被调用存储过程名称
                .registerStoredProcedureParameter("P_BRID", Float.class, ParameterMode.IN) // 注册参数
                .registerStoredProcedureParameter("P_YBKH", String.class, ParameterMode.IN)
                .registerStoredProcedureParameter("P_ERRMSG", String.class, ParameterMode.INOUT)
                .setParameter("P_BRID", brid)
                .setParameter("P_YBKH", ybkh);
        query.execute();
        String priceStr = (String) query.getOutputParameterValue("P_ERRMSG"); // 获取存储过程中的返回值
        return priceStr;
    }
    public String updateSfzh(Float brid,String sfzh) {
        StoredProcedureQuery query = entityManager
                .createStoredProcedureQuery("zksg.SP_ZKSG_sfzhxg@xec_link") // 被调用存储过程名称
                .registerStoredProcedureParameter("P_BRID", Float.class, ParameterMode.IN) // 注册参数
                .registerStoredProcedureParameter("P_SFZH", String.class, ParameterMode.IN)
                .registerStoredProcedureParameter("P_ERRMSG", String.class, ParameterMode.INOUT)
                .setParameter("P_BRID", brid)
                .setParameter("P_SFZH", sfzh);
        query.execute();
        String priceStr = (String) query.getOutputParameterValue("P_ERRMSG"); // 获取存储过程中的返回值
        return priceStr;
    }


}
