package com.fs.course.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fs.course.domain.FsCourseWatchLog;
import com.fs.course.domain.FsUserCourseVideo;
import com.fs.course.param.*;
import com.fs.course.vo.*;
import com.fs.sop.vo.QwRatingVO;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.ArrayList;
import java.util.List;

/**
 * 短链课程看课记录Mapper接口
 *
 * @author fs
 * @date 2024-09-18
 */
public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
    /**
     * 查询短链课程看课记录
     *
     * @param logId 短链课程看课记录主键
     * @return 短链课程看课记录
     */
    public FsCourseWatchLog selectFsCourseWatchLogByLogId(Long logId);

    /**
     * 查询短链课程看课记录列表
     *
     * @param fsCourseWatchLog 短链课程看课记录
     * @return 短链课程看课记录集合
     */
    public List<FsCourseWatchLog> selectFsCourseWatchLogList(FsCourseWatchLog fsCourseWatchLog);

    /**
     * 查询短链课程看课记录
     *
     * @param param 短链课程看课记录
     * @return 短链课程看课记录
     */
    @Select("SELECT wl.log_id, wl.log_type FROM " +
            "fs_course_watch_log  wl " +
            "left join crm_customer cc on wl.user_id=cc.user_id " +
            "left join qw_external_contact ec on wl.qw_external_contact_id=ec.id " +
            "WHERE " +
            " cc.customer_id = #{map.customerId} " +
            "and wl.video_id = #{map.videoId} " +
            "and ec.external_user_id= #{map.externalUserId} " )
    public FsCourseWatchLog selectFsCourseWatchLog(@Param("map") FsCourseWatchLogParam param);


    /**
     * 新增短链课程看课记录
     *
     * @param fsCourseWatchLog 短链课程看课记录
     * @return 结果
     */
    public int insertFsCourseWatchLog(FsCourseWatchLog fsCourseWatchLog);

    public int insertOrUpdateFsCourseWatchLog(FsCourseWatchLog fsCourseWatchLog);

    /**
     * 修改短链课程看课记录
     *
     * @param fsCourseWatchLog 短链课程看课记录
     * @return 结果
     */
    public int updateFsCourseWatchLog(FsCourseWatchLog fsCourseWatchLog);

    @Update("UPDATE fs_course_watch_log SET user_id = #{userId} WHERE qw_external_contact_id = #{externalUserId}")
    public int updateFsCourseWatchLogByQwExternalId(@Param("externalUserId") Long externalUserId,@Param("userId") Long userId);

    /**
     * 删除短链课程看课记录
     *
     * @param logId 短链课程看课记录主键
     * @return 结果
     */
    public int deleteFsCourseWatchLogByLogId(Long logId);

    /**
     * 批量删除短链课程看课记录
     *
     * @param logIds 需要删除的数据主键集合
     * @return 结果
     */
    public int deleteFsCourseWatchLogByLogIds(Long[] logIds);

    @Select("select * from fs_course_watch_log where user_id = #{userId} and video_id = #{videoId} and log_type = 2")
    FsCourseWatchLog getFinishCourseVideo(@Param("userId") Long userId, @Param("videoId") Long videoId);


    //临时看课记录
    @Select("select * from fs_course_watch_log where user_id = #{userId} and video_id = #{videoId} and company_user_id = #{companyUserId}")
    FsCourseWatchLog getWatchLogByTemporary(@Param("userId") Long userId,
                                          @Param("videoId") Long videoId,
                                          @Param("companyUserId") Long companyUserId);

    @Select("select * from fs_course_watch_log " +
            "where user_id = #{userId} " +
            "and video_id = #{videoId} " +
            "and qw_user_id = #{qwUserId} " +
            "and qw_external_contact_id = #{externalId}")
    FsCourseWatchLog getWatchCourseVideo(@Param("userId") Long userId, @Param("videoId") Long videoId,@Param("qwUserId") String qwUserId,@Param("externalId") Long externalId);

    @Select("select * from fs_course_watch_log " +
            "where qw_external_contact_id = #{externalId} " +
            "and video_id = #{videoId} " +
            "and qw_user_id = #{qwUserId} ")
    FsCourseWatchLog getWatchCourseVideoByExt( @Param("externalId") Long externalId, @Param("videoId") Long videoId,@Param("qwUserId") String qwUserId);

    @Select("select * from fs_course_watch_log " +
            "where video_id = #{videoId} " +
            "and qw_user_id = #{qwUserId} " +
            "and qw_external_contact_id = #{externalId} ")
    FsCourseWatchLog getWatchCourseLogVideoBySop(@Param("videoId") Long videoId,
                                                 @Param("qwUserId") String qwUserId,
                                                 @Param("externalId") Long externalId);

    List<FsCourseWatchLogListVO> selectFsCourseWatchLogListVO(@Param("maps") FsCourseWatchLogListParam param);

    List<FsCourseWatchLogListVO> selectFsCourseWatchLogListByParam(FsCourseWatchLogListParam param);

    @Select("select l.*,v.title,c.course_name from fs_course_watch_log l LEFT JOIN fs_user_course_video v ON v.video_id = l.video_id LEFT JOIN fs_user_course c ON c.course_id = l.course_id WHERE l.qw_external_contact_id =#{id} ORDER BY l.create_time  desc LIMIT 1  ")
    FsCourseWatchLogVO selectFsCourseWatchLogByExtId(Long id);

    @Select("select l.qw_external_contact_id,l.company_id,l.company_user_id,l.log_type,ext.`level`,l.qw_user_id FROM fs_course_watch_log l LEFT JOIN qw_external_contact ext ON ext.id =l.qw_external_contact_id  where l.sop_id=#{SopId} and  date(l.create_time)= CURDATE() and l.log_type =3 and l.video_id not in (select video_id from fs_user_course_video WHERE is_first=1 ) ")
    List<FsCourseWatchLogTaskVO> selectFsCourseWatchLogByDaySopId3(@Param("SopId")String SopId);

    @Select("select l.qw_external_contact_id,l.company_id,l.company_user_id,l.log_type,ext.`level`,l.qw_user_id FROM fs_course_watch_log l LEFT JOIN qw_external_contact ext ON ext.id =l.qw_external_contact_id  where l.sop_id=#{SopId} and  date(l.create_time)= CURDATE() and l.log_type =4 and l.video_id not in (select video_id from fs_user_course_video WHERE is_first=1 ) ")
    List<FsCourseWatchLogTaskVO> selectFsCourseWatchLogByDaySopId4(@Param("SopId")String SopId);

//    @Select("   SELECT\n" +
//            "            wl.log_type,\n" +
//            "            ec.level\n" +
//            "        FROM\n" +
//            "            fs_course_watch_log wl LEFT JOIN qw_external_contact ec on wl.qw_external_contact_id=ec.id\n" +
//            "        WHERE\n" +
//            "            wl.send_type = 2\n" +
//            "        and wl.qw_external_contact_id= #{externalId}\n" +
//            "        AND wl.create_time &gt;= DATE_SUB(CURDATE(), INTERVAL #{dayNum} DAY)\n" +
//            "        AND wl.create_time &lt; CURDATE()\n")

    @Select("SELECT\n" +
            "  wl.duration as watchDuration,\n" +
            "\tcv.duration as allDuration,\n" +
            "\tec.`level` AS levelType\n" +
            "FROM\n" +
            "\tfs_course_watch_log wl\n" +
            "\tLEFT JOIN qw_external_contact ec ON wl.qw_external_contact_id = ec.id\n" +
            "\tLEFT JOIN fs_user_course_video cv ON wl.video_id = cv.video_id \n" +
            "WHERE\n" +
            "\twl.send_type = 2 \n" +
            "\tAND wl.qw_external_contact_id = #{externalId} \n" +
            "\tAND wl.create_time >= DATE_SUB( CURDATE(), INTERVAL #{dayNum} DAY ) \n" +
            "\tAND wl.create_time < CURDATE() ")
    List<QwRatingVO> selectFsCourseWatchLogByExtIdRating(@Param("externalId") Long externalId, @Param("dayNum") Integer dayNum);

    @Select("select l.*,v.title,c.course_name from fs_course_watch_log l LEFT JOIN fs_user_course_video v ON v.video_id = l.video_id LEFT JOIN fs_user_course c ON c.course_id = l.course_id WHERE l.qw_external_contact_id =#{ExtId} and l.qw_user_id=#{QwUserId} and DATE(l.create_time) =CURDATE() ORDER BY l.create_time  desc LIMIT 1  ")
    FsCourseWatchLogVO selectFsCourseWatchLogByExtIdAndQwUserId(@Param("ExtId")String ExtId,@Param("QwUserId")Long QwUserId);

    void insertFsCourseWatchLogBatch(@Param("watchLogs") List<FsCourseWatchLog> watchLogsToInsert);

    @Select("select * from fs_course_watch_log where log_type = 1 ")
    List<FsCourseWatchLog> findAllWatchingLogs();


    @Select("SELECT * \n" +
            "FROM fs_course_watch_log \n" +
            "WHERE log_type = 4 AND last_heartbeat_time >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 1 HOUR) ")
    List<FsCourseWatchLog> findWatchLogsExit();


    @Select("SELECT * \n" +
            "FROM fs_course_watch_log \n" +
            "WHERE (log_type = 1 or log_type = 4) AND finish_time is not null ")
    List<FsCourseWatchLog> findWatchLogsExitAndWatching();

    @Select("select * from fs_course_watch_log where log_type = 2 and send_finish_msg = 0 AND finish_time >= CURRENT_DATE\n" +
            "AND finish_time < CURRENT_DATE + INTERVAL 1 DAY")
    List<FsCourseWatchLog> selectFsCourseWatchLogFinish();

    @Select({"<script> " +
            "SELECT \n" +
            "o.video_id,o.company_id,o.qw_user_id,DATE(o.create_time) create_time,qu.qw_user_name,v.title videoName,uc.course_name,\n" +
            "SUM(CASE WHEN o.log_type = '1' THEN 1 ELSE 0 END) AS type1,\n" +
            "SUM(CASE WHEN o.log_type = '2' THEN 1 ELSE 0 END) AS type2,\n" +
            "SUM(CASE WHEN o.log_type = '3' THEN 1 ELSE 0 END) AS type3,\n" +
            "SUM(CASE WHEN o.log_type = '4' THEN 1 ELSE 0 END) AS type4\n" +
            "FROM fs_course_watch_log o\n" +
            "LEFT JOIN qw_user qu on qu.id=o.qw_user_id\n" +
            "LEFT JOIN fs_user_course_video v on v.video_id=o.video_id \n" +
            "LEFT JOIN fs_user_course uc on uc.course_id=v.course_id\n" +
            "where o.company_id=#{companyId}  " +
            "<if test= 'sTime != null '> " +
            "       and DATE(o.create_time) &gt;= DATE(#{sTime})\n" +
            "</if>\n" +
            "<if test='eTime != null '> " +
            "      and DATE(o.create_time) &lt;= DATE(#{eTime})\n" +
            "</if>" +
            "<if test ='nickName !=null and nickName!=\"\"'>\n" +
            "   and qu.qw_user_name like concat( #{nickName}, '%')\n" +
            "</if>" +
            "<if test ='courseId !=null'> " +
            "     and o.course_id = #{courseId} " +
            "</if>" +
            "<if test ='videoId !=null'> " +
            "     and o.video_id = #{videoId} " +
            "</if>" +
            "GROUP BY o.video_id,o.qw_user_id,DATE(o.create_time)\n" +
            "ORDER BY o.video_id ,DATE(o.create_time) \n"+
            "</script>"})
    List<FsCourseWatchLogStatisticsListVO> selectFsCourseWatchLogStatisticsListVO(FsCourseWatchLogStatisticsListParam param);


    ArrayList<FsCourseWatchLogByFinishTimeParam> selectFsCourseWatchLogByFinishTime();

    void batchUpdateWatchLog(@Param("list") List<FsCourseWatchLog> logs);

    List<FsCourseUserStatisticsListVO> selectFsCourseUserStatisticsListVO(FsCourseUserStatisticsListParam param);

    @Select({"<script> " +
            "select MIN(o.create_time) createTime,ANY_VALUE(qu.qw_user_name) qwUserName ,ext.name externalUserName,ext.create_time userCreateTime from fs_course_watch_log o LEFT JOIN qw_user qu on qu.id=o.qw_user_id LEFT JOIN qw_external_contact ext ON ext.id =  o.qw_external_contact_id where log_type=2 and o.company_id=#{companyId} " +
            "<if test= 'sTime != null '> " +
            "       and DATE(o.create_time) &gt;= DATE(#{sTime})\n" +
            "</if>\n" +
            "<if test='eTime != null '> " +
            "      and DATE(o.create_time) &lt;= DATE(#{eTime})\n" +
            "</if>" +
            "<if test ='nickName !=null and nickName!=\"\"'>\n" +
            "   and qu.qw_user_name like concat('%', #{nickName}, '%')\n" +
            "</if>"+
            " GROUP BY o.qw_external_contact_id"+
            "</script>"})
    List<FsCourseOverVO> selectFsCourseWatchLogOverStatisticsListVO(FsCourseOverParam param);


    void batchUpdateWatchLogSendMsg(@Param("list") List<FsCourseWatchLog> logs);

    @Select("SELECT l.qw_external_contact_id,l.log_type,l.qw_user_id,l.create_time ,u.first_time,u.create_time lineTime FROM fs_course_watch_log  l " +
            "LEFT JOIN qw_external_contact u ON u.id=l.qw_external_contact_id  " +
            " WHERE  DATE(l.create_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY) and l.video_id =#{videoId}")
    List<FsQwCourseWatchLogVO> selectFsCourseWatchLogByNoDayAndVoidId(Long videoId);

    @Select("SELECT l.qw_external_contact_id,l.log_type,l.qw_user_id,l.create_time ,u.first_time,u.create_time lineTime FROM fs_course_watch_log  l " +
            "LEFT JOIN qw_external_contact u ON u.id=l.qw_external_contact_id  " +
            " WHERE  DATE(l.create_time) = DATE_SUB(CURDATE(), INTERVAL 2 DAY) and l.video_id =#{videoId}")
    List<FsQwCourseWatchLogVO> selectFsCourseWatchLogByNoDayAndVoidId2(Long videoId);


    @Select("SELECT l.qw_external_contact_id,l.log_type,l.qw_user_id,l.create_time ,u.first_time,u.create_time lineTime FROM fs_course_watch_log  l " +
            "LEFT JOIN qw_external_contact u ON u.id=l.qw_external_contact_id  " +
            " WHERE  DATE(l.create_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY) and l.sop_id =#{videoId}")
    List<FsQwCourseWatchLogVO> selectFsCourseWatchLogBySopId(String id);

    @Select("SELECT * FROM fs_course_watch_log  WHERE  DATE(create_time) = CURDATE() and video_id in (select video_id from fs_user_course_video WHERE is_first=1 ) ")
    List<FsQwCourseWatchLogVO> selectFsCourseWatchLogByVideoId();

    @Select("SELECT qw_external_contact_id FROM fs_course_watch_log  WHERE log_type=2 and DATE(create_time) = CURDATE() ")
    List<Long> selectFsCourseWatchLogByFinish();
}
