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

import com.rf.psychological.base.repository.BaseRepository;
import com.rf.psychological.dao.dto.InstitutionRecordingDTO;
import com.rf.psychological.dao.dto.InstitutionRecordingUserDTO;
import com.rf.psychological.dao.dto.InstitutionRecordingUsersDTO;
import com.rf.psychological.scale.dao.model.UserRecordEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
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;

/**
 * @author zsy
 * @description:用户测试记录
 * @date 2021/6/17 15:55
 */
public interface UserRecordRepository extends BaseRepository<UserRecordEntity, String> {

    /**
     * 认知任务测试次数统计
     *
     * @return
     */
    @Query(value = "SELECT * FROM t_user_record WHERE flag IN ('RIVEN','GO_NO-GO','MEMORY','ALERTNESS','ADDITION','RHYTHM','SHAPE','MOVEMENT','ANT','MOCA','MMSE','CDT','BIC','RTC','SHAPE2','MEMORY_YATAI','ALERTNESS_YATAI','SHAPE_YATAI','ANT_YATAI','ANTFISH')", nativeQuery = true)
    List<UserRecordEntity> testAmount();

    /**
     * 删除用户测试记录
     *
     * @param phone
     * @param institutionNo
     */
    @Transactional
    @Modifying(clearAutomatically = true)
    void deleteAllByPhoneAndInstitutionNo(@Param("phone") String phone, @Param("institutionNo") String institutionNo);

    /**
     * 根据账号和机构号查询用户测试记录
     *
     * @return
     */
    //@Query(value="select id,flag,phone,test_date,file_name,test_result,type,name from t_user_record where phone = :phone order by test_date desc limit :pageNum ,:pageSize ",nativeQuery=true)
    @Query(value = "select a.id,a.flag,b.pet_name as phone,a.test_date,a.file_name,a.test_result,a.type,a.name,a.img,a.test_record,a.test_results,b.institution_no,a.test_plan_id " +
            "from t_user_record a INNER JOIN t_user_info b ON a.phone = b.phone and  b.role_type='1' and a.institution_no = b.institution_no where binary a.phone = :phone and b.institution_no= :institutionNo and if(:searchKey is not null and :searchKey != '', a.name like CONCAT('%', :searchKey, '%'), 1 = 1) order by test_date desc limit :pageNum ,:pageSize ", nativeQuery = true)
    List<UserRecordEntity> getTestListByPhone(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize, @Param("phone") String phone, @Param("institutionNo") String institutionNo, @Param("searchKey") String searchKey);


    /**
     * 根据手机号和记录类别查询
     *
     * @param pageNum
     * @param pageSize
     * @param phone
     * @param type
     * @return
     */
    @Query(value = "select * from t_user_record where binary phone = :phone and institution_no= :institutionNo and test_date>:beginTime and test_date<:endTime " +
            "and type= :type order by test_date desc limit :pageNum ,:pageSize ", nativeQuery = true)
    List<UserRecordEntity> getListByPhoneAndTypeAndTime(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize, @Param("phone") String phone, @Param("institutionNo") String institutionNo, @Param("type") String type, @Param("beginTime") String beginTime, @Param("endTime") String
            endTime);

    /**
     * 根据手机号和类别查询用户测试记录总条数
     *
     * @return
     */
    @Query(value = "select count(1) from t_user_record where binary phone = :phone and institution_no= :institutionNo and test_date>:beginTime and test_date<:endTime " +
            "and type= :type", nativeQuery = true)
    int countByPhoneAndTypeAndTime(@Param("phone") String phone, @Param("institutionNo") String institutionNo, @Param("type") String type, @Param("beginTime") String beginTime, @Param("endTime") String
            endTime);

    /**
     * 根据手机号和记录类别查询
     *
     * @param pageNum
     * @param pageSize
     * @param phone
     * @param type
     * @return
     */
    @Query(value = "select * from t_user_record where binary phone = :phone and institution_no= :institutionNo " +
            "and type= :type order by test_date desc limit :pageNum ,:pageSize ", nativeQuery = true)
    List<UserRecordEntity> getListByPhoneAndType(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize, @Param("phone") String phone, @Param("institutionNo") String institutionNo, @Param("type") String type);

    /**
     * 根据手机号和类别查询用户测试记录总条数
     *
     * @return
     */
    @Query(value = "select count(1) from t_user_record where binary phone = :phone and institution_no= :institutionNo " +
            "and type= :type", nativeQuery = true)
    int countByPhoneAndType(@Param("phone") String phone, @Param("institutionNo") String institutionNo, @Param("type") String type);

    /**
     * 根据手机号查询用户测试记录总条数
     *
     * @return
     */
    @Query(value = "select count(1) from t_user_record where binary phone = :phone and institution_no = :institutionNo and if(:searchKey is not null and :searchKey != '', name like CONCAT('%', :searchKey, '%'), 1 = 1)", nativeQuery = true)
    int allNumByPhone(@Param("phone") String phone, @Param("institutionNo") String institutionNo, @Param("searchKey") String searchKey);

    /**
     * 根据id查询数据
     *
     * @return
     */
    @Query(value = "select id,flag,phone,test_date,file_name,test_result,type,name,img,test_record,test_results,institution_no,test_plan_id from t_user_record where id = :id ", nativeQuery = true)
    UserRecordEntity getUserRecordById(@Param("id") String id);

    UserRecordEntity findUserRecordEntitiesById(String id);

    /**
     * 用户查询靶向神经振荡评估与训练记录
     *
     * @return
     */
    @Query(value = "select id,flag,phone,test_date,file_name,test_result,type,name,img,test_record,test_results,institution_no,test_plan_id " +
            "from t_user_record where binary phone = :phone and flag = 'RHYTHM' and test_plan_id=:testPlanId and institution_no=:institutionNo ORDER BY test_date DESC LIMIT 1", nativeQuery = true)
    UserRecordEntity getRHYTHM(@Param("phone") String phone, @Param("institutionNo") String institutionNo, @Param("testPlanId") String testPlanId);

    /**
     * 用户查询枪林弹雨
     *
     * @return
     */
    @Query(value = "select id,flag,phone,test_date,file_name,test_result,type,name,img,test_record,test_results,institution_no,test_plan_id from t_user_record where binary phone = :phone and flag = 'GUNSBULLETS' and institution_no=:institutionNo ORDER BY test_date DESC LIMIT 1", nativeQuery = true)
    List<UserRecordEntity> getGUNSBULLETS(@Param("phone") String phone, @Param("institutionNo") String institutionNo);

    /**
     * 查询机构下所有用户已经做的测试记录
     *
     * @param institutionNo
     * @param
     * @return
     */
    @Query(value = "select distinct tur.name as name,tur.flag as flag,tur.type as type from t_user_info tui join t_user_record tur on tui.phone = tur.phone and tui.role_type='1' and tui.institution_no=tur.institution_no where tui.institution_no = :institutionNo and tur.type = :type and  ( if(:searchKey is not null and :searchKey!='',tur.name like CONCAT('%',:searchKey,'%')  ,1=1) or if(:searchKey is not null and :searchKey!='',tur.flag like CONCAT('%',:searchKey,'%')  ,1=1) ) and " +
            "if(:beginTime is not null and :beginTime!='',tur.test_date>:beginTime ,1=1)  and if(:endTime is not null and :endTime!='', tur.test_date<:endTime ,1=1)" +
            "limit :pageNum ,:pageSize ", nativeQuery = true)
    List<InstitutionRecordingDTO> getInstitutionUserRecording(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize, @Param("institutionNo") String institutionNo, @Param("type") String type, @Param("searchKey") String searchKey, @Param("beginTime") String beginTime, @Param("endTime") String
            endTime);


    @Query(value = "select count(distinct name) from t_user_info tui,t_user_record tur where tui.phone = tur.phone and tui.institution_no=tur.institution_no and tui.role_type='1' and tui.institution_no = :institutionNo and type = :type and ( if(:searchKey is not null and :searchKey!='',tur.name like CONCAT('%',:searchKey,'%')  ,1=1) or if(:searchKey is not null and :searchKey!='',tur.flag like CONCAT('%',:searchKey,'%')  ,1=1) ) and " +
            "if(:beginTime is not null and :beginTime!='',tur.test_date>:beginTime ,1=1)  and if(:endTime is not null and :endTime!='', tur.test_date<:endTime ,1=1)", nativeQuery = true)
    int allCountByInstitutionNo(@Param("institutionNo") String institutionNo, @Param("type") String type, @Param("searchKey") String searchKey, @Param("beginTime") String beginTime, @Param("endTime") String
            endTime);


    /**
     * 查询机构下测试量表下的用户
     *
     * @param pageable
     * @param institutionNo
     * @param name
     * @return
     */
    @Query(value = "select tui.phone,tui.pet_name as petName,tui.password,tui.gender,tui.birthday,tui.profession,tui.institution_name as institutionName" +
            ",tui.institution_no as institutionNo,tui.user_status as userStatus,tui.addition_info as additionInfo,tur.id as id,tur.test_date as testDate" +
            ",tur.test_result as testResult, tgi.group_name as gid from t_user_info tui join t_group_info tgi ON tgi.id = tui.g_id " +
            "join t_user_record tur on tur.phone = tui.phone  and tui.role_type='1' " +
            "and tui.institution_no=tur.institution_no where  tui.institution_no= :institutionNo and tur.name= :name and " +
            "if(:beginFormat is not null and :beginFormat!='',tur.test_date>:beginFormat ,1=1)  " +
            "and if(:endFormat is not null and :endFormat!='', tur.test_date<:endFormat ,1=1) " +
            "and if(:groupId is not null and :groupId!='',(tui.g_id = :groupId) ,1=1) " +
            "and ( if(:searchKey is not null and :searchKey!='',tui.pet_name like CONCAT('%',:searchKey,'%')  ,1=1) " +
            "or if(:searchKey is not null and :searchKey!='',tui.phone like CONCAT('%',:searchKey,'%')  ,1=1) ) order by tur.test_date desc ", nativeQuery = true)
    List<InstitutionRecordingUserDTO> getInstitutionRecording(Pageable pageable, @Param("institutionNo") String institutionNo, @Param("name") String name
            , @Param("searchKey") String searchKey, @Param("beginFormat") String beginFormat, @Param("endFormat") String endFormat, @Param("groupId") String groupId);

    @Query(value = "select count(tui.id) from t_user_info tui join t_group_info tgi ON tgi.id = tui.g_id " +
            "join t_user_record tur on tur.phone = tui.phone  and tui.role_type='1' and tui.institution_no=tur.institution_no " +
            "where  tui.institution_no= :institutionNo and tur.name= :name " +
            "and if(:beginFormat is not null and :beginFormat!='',tur.test_date>:beginFormat ,1=1) " +
            "and if(:endFormat is not null and :endFormat!='', tur.test_date<:endFormat ,1=1) " +
            "and if(:groupId is not null and :groupId!='',(tui.g_id = :groupId) ,1=1) " +
            "and ( if(:searchKey is not null and :searchKey!='',tui.pet_name like CONCAT('%',:searchKey,'%')  ,1=1) or if(:searchKey is not null and :searchKey!='',tui.phone like CONCAT('%',:searchKey,'%')  ,1=1) )order by tur.test_date desc ", nativeQuery = true)
    int allCountInstitutionRecording(@Param("institutionNo") String institutionNo, @Param("name") String name, @Param("searchKey") String searchKey
            , @Param("beginFormat") String beginFormat, @Param("endFormat") String endFormat, @Param("groupId") String groupId);


    List<UserRecordEntity> findAllByInstitutionNoAndTestPlanIdAndPhoneAndType(String institutionNo, String testPlanId, String phone, String type);

    /**
     * 根据id修改信息
     *
     * @param
     * @return
     */
    @Transactional
    @Modifying(clearAutomatically = true)
    @Query(value = "UPDATE t_user_record SET test_result = :testResult WHERE id = :id ", nativeQuery = true)
    void updateById(@Param("id") String id, @Param("testResult") String testResult);

    @Query(value = "select tui.id             userId,\n" +
            "       gender,\n" +
            "       pet_name           petName,\n" +
            "       birthday,\n" +
            "       profession,\n" +
            "       addition_info      additionInfo,\n" +
            "       institution_name   institutionName,\n" +
            "       tui.institution_no institutionNo,\n" +
            "       user_status        userStatus,\n" +
            "       g_id               groupId,\n" +
            "       model_phone        modelPhone,\n" +
            "       tur.id             recordingId,\n" +
            "       flag,\n" +
            "       tui.phone,\n" +
            "       test_date          testDate,\n" +
            "       file_name          fileName,\n" +
            "       test_result        testResult,\n" +
            "       type,\n" +
            "       name,\n" +
            "       img,\n" +
            "       test_record        testRecord,\n" +
            "       test_results       testResults,\n" +
            "       test_plan_id       testPlanId  from t_user_info tui join t_user_record tur on tur.phone = tui.phone and  tui.role_type='1' AND tur.institution_no =tui.institution_no " +
            "where  tui.institution_no= :institutionNo and tur.name= :name " +
            "and if(:groupId is not null and :groupId!='',(tui.g_id = :groupId) ,1=1) " +
            "and if(:searchName is not null and :searchName!='',tui.phone like CONCAT('%',:searchName,'%') or tui.pet_name like CONCAT('%',:searchName,'%') ,1=1)", nativeQuery = true)
    List<InstitutionRecordingUsersDTO> getInstitution(@Param("institutionNo") String institutionNo, @Param("name") String name, @Param("searchName") String searchName
            , @Param("groupId") String groupId);

    @Query(value = "select tui.id             userId,\n" +
            "       gender,\n" +
            "       pet_name           petName,\n" +
            "       birthday,\n" +
            "       profession,\n" +
            "       addition_info      additionInfo,\n" +
            "       institution_name   institutionName,\n" +
            "       tui.institution_no institutionNo,\n" +
            "       user_status        userStatus,\n" +
            "       g_id               groupId,\n" +
            "       model_phone        modelPhone,\n" +
            "       tur.id             recordingId,\n" +
            "       flag,\n" +
            "       tui.phone,\n" +
            "       test_date          testDate,\n" +
            "       file_name          fileName,\n" +
            "       test_result        testResult,\n" +
            "       type,\n" +
            "       name,\n" +
            "       img,\n" +
            "       test_record        testRecord,\n" +
            "       test_results       testResults,\n" +
            "       test_plan_id       testPlanId " +
            "from t_user_info tui  join t_user_record tur on tur.phone = tui.phone and  tui.role_type='1'  and tui.institution_no=tur.institution_no " +
            "where tui.institution_no= :institutionNo and tur.name= :name and test_date >= :beginTime and test_date <= :endTime  " +
            "and if(:groupId is not null and :groupId!='',(tui.g_id = :groupId) ,1=1) " +
            "and if(:searchName is not null and :searchName!='',tui.phone like CONCAT('%',:searchName,'%') or tui.pet_name like CONCAT('%',:searchName,'%') ,1=1)", nativeQuery = true)
    List<InstitutionRecordingUsersDTO> getInstitution(@Param("institutionNo") String institutionNo, @Param("name") String name, @Param("searchName") String searchName
            , @Param("beginTime") String beginTime, @Param("endTime") String endTime, @Param("groupId") String groupId);

    @Query(value = "SELECT * FROM t_user_record WHERE phone in(SELECT phone FROM t_user_info WHERE institution_no = '10007')", nativeQuery = true)
    List<UserRecordEntity> findAll1();

    //@Query(value = "SELECT * FROM t_user_record WHERE test_plan_id = :testPlanId", nativeQuery = true)
    @Query(value = "SELECT * FROM t_user_record WHERE test_plan_id = 'ff80818180c27c7a0180cc18180d0280' AND phone in(\n" +
            "select phone from t_user_info where institution_no = '10017' and addition_info = '20220518' and model_phone !=0\n" +
            ") and test_date <= '2022年05月23日16时30分00秒';", nativeQuery = true)
    List<UserRecordEntity> getUserRecordByPlanId(@Param("testPlanId") String testPlanId);

    @Query(value = "select id,flag,phone,test_date,file_name,test_result,type,name,img,test_record,test_results,institution_no,test_plan_id from t_user_record where binary phone = :phone and flag = :flag", nativeQuery = true)
    List<UserRecordEntity> getuserRecordByPhone(@Param("phone") String phone,@Param("flag") String flag);

    @Query(value = "select tui.id             userId,\n" +
            "       gender,\n" +
            "       pet_name           petName,\n" +
            "       birthday,\n" +
            "       profession,\n" +
            "       addition_info      additionInfo,\n" +
            "       institution_name   institutionName,\n" +
            "       tui.institution_no institutionNo,\n" +
            "       user_status        userStatus,\n" +
            "       g_id               groupId,\n" +
            "       model_phone        modelPhone,\n" +
            "       tur.id             recordingId,\n" +
            "       flag,\n" +
            "       tui.phone,\n" +
            "       test_date          testDate,\n" +
            "       file_name          fileName,\n" +
            "       test_result        testResult,\n" +
            "       type,\n" +
            "       name,\n" +
            "       img,\n" +
            "       test_record        testRecord,\n" +
            "       test_results       testResults,\n" +
            "       test_plan_id       testPlanId  from t_user_info tui  join t_user_record tur on tur.phone = tui.phone and tui.role_type='1' AND tur.institution_no =tui.institution_no " +
            "where tur.id= :id ", nativeQuery = true)
    InstitutionRecordingUsersDTO getRecordingUsersDTOById(@Param("id") String id);

    //    @Query(value = "SELECT  new com.rf.psychological.dao.model.ReturnEntity(a.flag,COUNT(a.flag)) FROM t_user_record  a WHERE a.flag IN ('RIVEN','GO_NO-GO','MEMORY','ALERTNESS','ADDITION') GROUP BY a.flag",nativeQuery=true)
    /*@Query(value="select  new com.rf.psychological.dao.model.ReturnEntity(r.flag,COUNT(r.flag))  from t_user_record as r  where r.flag in ('RIVEN','GO_NO-GO','MEMORY','ALERTNESS','ADDITION')   GROUP BY r.flag",nativeQuery = true)
    List<ReturnEntity> testAmount();*/

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

    @Query(value = "select * from t_user_record where binary phone = :userId and id = :resultId and institution_no = :institutionNo ", nativeQuery = true)
    UserRecordEntity getuserRecordByIdAndInstitutionNoAndPhone(@Param("resultId") String resultId,@Param("userId") String userId,@Param("institutionNo") String institutionNo);

    @Query(value = "select id,flag,phone,test_date,file_name,test_result,type,name,img,test_record,test_results,institution_no,test_plan_id " +
            "from t_user_record where binary phone = :phone and flag = :flag and test_plan_id=:testPlanId and institution_no=:institutionNo ORDER BY test_date DESC LIMIT 1", nativeQuery = true)
    UserRecordEntity findByPhoneAndTestPlanIdAndInstitution(@Param("institutionNo") String institutionNo, @Param("phone") String phone, @Param("testPlanId") String testPlanId, @Param("flag") String flag);

    @Query(value = "select count(1) from t_user_record where institution_no=:institutionNo",nativeQuery = true)
    int  findAllByInstitutionNo(@Param("institutionNo") String institutionNo);

    @Query(value = "SELECT test_date from t_user_record WHERE institution_no=:institutionNo ORDER BY test_date LIMIT :i,1",nativeQuery = true)
    String findByTestNum(@Param("institutionNo") String institutionNo,@Param("i")int i);

    /**
     * 微博分享-通过手机号查询测试记录
     * @param modelPhone
     * @return
     */
    @Query(value = "SELECT * FROM t_user_record WHERE id in(" +
            "SELECT result_id FROM t_order_info WHERE order_status = :orderStatus AND user_id in(" +
            "SELECT id FROM t_user_info WHERE model_phone = :modelPhone))", nativeQuery = true)
    Page<UserRecordEntity> getRecordByModelPhone(@Param("modelPhone") String modelPhone, @Param("orderStatus") String orderStatus, Pageable pageable);


    int countAllByFlagAndTestDateGreaterThanEqual(String flag,String testDate);
}
