package com.rf.psychological.user.dao.repository;

import com.rf.psychological.base.repository.BaseRepository;
import com.rf.psychological.user.dao.model.UserEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/**
 * @author zsy
 * @description:登录认证
 * @date 2021/6/17 15:55
 */
public interface UserRepository extends BaseRepository<UserEntity, String> {

    /**
     * 根据手机号查询
     *
     * @return
     */
    @Query(value = "select * from t_user_info where binary phone = :phone ", nativeQuery = true)
    UserEntity findPhone(@Param("phone") String phone);


    Optional<UserEntity> findById(String id);

    @Transactional
    @Modifying(clearAutomatically = true)
    void deleteAllByInstitutionNo(String institutionNo);

    /**
     * 根据手机号修改密码
     *
     * @return
     */
    @Transactional
    @Modifying(clearAutomatically = true)
    @Query(value = "update t_user_info set password = :password " +
            "where binary phone = :phone and institution_no =:institutionNo and role_type =:roleType", nativeQuery = true)
    void updatePassword(@Param("phone") String phone, @Param("password") String password, @Param("institutionNo") String institutionNo, @Param("roleType") String roleType);


    /**
     * 根据机构查询用户列表
     *
     * @param pageNum
     * @param pageSize
     * @param searchKey
     * @param institutionNo
     * @return
     */
    @Query(value = "select tui.id,gender,password,pet_name,phone,birthday,profession,addition_info,institution_name" +
            ",tui.institution_no,user_status,tgi.group_name as g_id,model_phone,role_type " +
            "from t_user_info tui join t_group_info tgi ON tgi.id = tui.g_id where tui.institution_no = :institutionNo   and role_type ='1' and  " +
            " if(:searchKey is not null and :searchKey!='',(pet_name like %:searchKey% or phone like %:searchKey% ) , 1=1) " +
            "and if(:status is not null and :status!='',(tui.user_status = :status) , 1=1) " +
            "and if(:groupId is not null and :groupId!='',(tui.g_id = :groupId) , 1=1) limit :pageNum ,:pageSize ", nativeQuery = true)
    List<UserEntity> getUserListByInstitutionNo(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize, @Param("searchKey") String searchKey
            , @Param("institutionNo") String institutionNo, @Param("status") String status, @Param("groupId") String groupId);


    @Query(value = "select count(1) from t_user_info " +
            "where institution_no = :institutionNo and role_type = '1' " +
            "and if(:searchKey is not null and :searchKey!='',(pet_name like %:searchKey% or phone like %:searchKey% ) , 1=1) " +
            "and if(:status is not null and :status!='',(t_user_info.user_status = :status ), 1=1) " +
            "and if(:groupId is not null and :groupId!='',(t_user_info.g_id = :groupId) , 1=1)", nativeQuery = true)
    int allNum(@Param("searchKey") String searchKey, @Param("institutionNo") String institutionNo, @Param("status") String status, @Param("groupId") String groupId);

    /**
     * 用户审核
     *
     * @param status
     * @param id
     */
    @Transactional
    @Modifying(clearAutomatically = true)
    @Query(value = "update t_user_info set user_status = :status where id = :id ", nativeQuery = true)
    void updateUserStatus(@Param("status") String status, @Param("id") String id);


    /**
     * @param pageNum
     * @param pageSize
     * @param institutionNo
     * @param searchKey
     * @return
     */
    @Query(value = "select distinct tui.id,gender,password,pet_name,tui.phone,birthday,profession,addition_info,institution_name,tui.institution_no" +
            ",user_status,tgi.group_name as g_id,model_phone,role_type from t_user_info tui join t_group_info tgi ON tgi.id = tui.g_id " +
            "join t_user_record tur on  tui.phone=tur.phone and tui.institution_no=tur.institution_no " +
            "where tui.institution_no = :institutionNo  and role_type ='1' and if(:groupId is not null and :groupId!='',(tui.g_id = :groupId) , 1=1) " +
            "and (pet_name like %:searchKey% or tui.phone like %:searchKey% ) order by id  limit :pageNum ,:pageSize ", nativeQuery = true)
    List<UserEntity> getTestListByInstitutionNo(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize, @Param("institutionNo") String institutionNo
            , @Param("searchKey") String searchKey, @Param("groupId") String groupId);

    @Query(value = "select count(distinct tui.id) from t_user_info tui join t_user_record tur on  tui.phone=tur.phone and tui.institution_no=tur.institution_no " +
            "where tui.institution_no = :institutionNo  and role_type ='1' and if(:groupId is not null and :groupId!='',(tui.g_id = :groupId) , 1=1) " +
            "and (pet_name like %:searchKey% or tui.phone like %:searchKey% )", nativeQuery = true)
    int allNumByInstitutionNo(@Param("institutionNo") String institutionNo, @Param("searchKey") String searchKey, @Param("groupId") String groupId);

    UserEntity findByPhoneAndInstitutionNoAndRoleType(String phone,String institutionNo,String roleType);
    UserEntity findByPhoneAndInstitutionNo(String phone,String institutionNo);

    /**
     * 通过手机号删除用户
     *
     * @param phone
     */
    @Transactional
    @Modifying(clearAutomatically = true)
    void deleteByPhoneAndInstitutionNo(@Param("phone") String phone, @Param("institutionNo") String institutionNo);


    /**
     * 更改用户的组状态
     *
     * @param gId
     * @param id
     */
    @Transactional
    @Modifying(clearAutomatically = true)
    @Query(value = "update t_user_info set g_id = :gId where id = :id", nativeQuery = true)
    void updateUserGroup(@Param("gId") String gId, @Param("id") String id);

    @Query(value = "select tui.id, gender, password, pet_name, phone, birthday, profession, addition_info, institution_name, tui.institution_no, user_status,tui.g_id,model_phone,role_type " +
            "from t_group_info tgi" +
            "   join t_user_info tui on tgi.id = tui.g_id " +
            "where tui.g_id = ?1 ", nativeQuery = true)
    List<UserEntity> findUsersInGroup(String gId);

    /**
     * 查询机构下没有组的用户
     */
    @Query(value = "select * from t_user_info where institution_no =?1 and t_user_info.g_id =?2 and if(?3 is not null and ?3!='',(t_user_info.pet_name like CONCAT('%',?3,'%') or phone like CONCAT('%',?3,'%') or profession like CONCAT('%',?3,'%')) , 1=1) "
            , countQuery = "select count(*) from t_user_info where institution_no =?1 and t_user_info.g_id =?2 and if(?3 is not null and ?3!='',(t_user_info.pet_name like CONCAT('%',?3,'%') or phone like CONCAT('%',?3,'%') or profession like CONCAT('%',?3,'%')) , 1=1)  ", nativeQuery = true)
    Page<UserEntity> findUserNoGroup(@Param("institutionNo") String institutionNo, @Param("gId") String gId, String searchKey, @Param("pageable") Pageable pageable);

    /**
     * 校验用户是否已注册
     *
     * @param phone
     * @return
     */
    @Query(value = "select pet_name from  t_user_info where binary phone = :phone ", nativeQuery = true)
    String checkUser(@Param("phone") String phone);

    /**
     * 查询没有某一测试计划的人员名单
     *
     * @param institutionNo 机构编号
     * @param testPlanId    测试计划id
     * @param searchKey     搜索关键词
     * @param pageable      分页首页和每页个数
     * @return
     */
    @Query(value = "select *\n" +
            "from t_user_info where institution_no=?1 and role_type='1' and user_status='2' and not exists(select 1 from t_test_plan_user where u_id = t_user_info.id and test_plan_id=?2) " +
            "and if(?3 is not null and ?3!='',(t_user_info.pet_name like CONCAT('%',?3,'%') or phone like concat('%',?3,'%')) , 1=1)",
            countQuery = "select count(*)\n" +
                    "from t_user_info where institution_no=?1 and role_type='1' and user_status='2' and not exists(select 1 from t_test_plan_user where u_id = t_user_info.id and test_plan_id=?2) " +
                    "and if(?3 is not null and ?3!='',(t_user_info.pet_name like CONCAT('%',?3,'%') or phone like concat('%',?3,'%')) , 1=1)", nativeQuery = true)
    Page<UserEntity> findUserNoTestPlan(String institutionNo, String testPlanId, String searchKey, Pageable pageable);

    @Query(value = "SELECT * FROM t_user_info WHERE id in(SELECT u_id FROM t_test_plan_user WHERE test_plan_id = :id) ", nativeQuery = true)
    List<UserEntity> getuserListByMPhone(@Param("id") String id);


    /**
     * 查询分组编号==0 的用户所在的组织编号,用于定时任务
     *
     * @param groupId
     * @return
     */
    @Query(value="select distinct institution_no from  t_user_info where g_id = :groupId ",nativeQuery=true)
    List<String> findInstitutionNosByGroupId(@Param("groupId") String groupId);

    /**
     * 更新用户分组信息
     *
     * @param institutionNo 机构编号
     * @param oldGroupId    原分组编号
     * @param newGroupId    新分组编号
     */
    /**
     * 修改用户分组编号
     * @param oldGroupId 原分组id
     * @param newGroupId 新分组id
     */
    @Transactional
    @Modifying(clearAutomatically = true)
    @Query(value = "update t_user_info set g_id = :newGroupId " +
            "where g_id = :oldGroupId and institution_no = :institutionNo ", nativeQuery = true)
    void updateUserGroup(@Param("institutionNo") String institutionNo, @Param("oldGroupId") String oldGroupId, @Param("newGroupId") String newGroupId);

    @Query(value="select id,gender,password,pet_name,phone,birthday,profession,addition_info,institution_name,institution_no,user_status,g_id,model_phone,role_type from t_user_info where id in(:userIdList)" ,nativeQuery = true)
    List<UserEntity> getUserByIds(@Param("userIdList") List<String> userIdList);


    /**
     * 审核机构用户
     *
     * @param phone
     * @param userStatus
     */
    @Transactional
    @Modifying(clearAutomatically = true)
    @Query(value = "update t_institution_user set user_status = :userStatus where binary phone = :phone and institution_no=:institutionNo", nativeQuery = true)
    void updateUserStatusByPhone(@Param("phone") String phone, @Param("userStatus") String userStatus, @Param("institutionNo") String institutionNo);

    /**
     * 根据手机号和机构编号查询用户
     * @param modelPhone
     * @param institutionNo
     * @param roleType
     * @return
     */
    UserEntity findByModelPhoneAndInstitutionNoAndRoleType(String modelPhone,String institutionNo,String roleType);

    @Query(value="select * from t_user_info where user_status = :userStatus and institution_no=:institutionNo" ,nativeQuery = true)
    List<UserEntity> findByStatus(@Param("institutionNo") String institutionNo, @Param("userStatus") String userStatus);
}
