package cn.teammodel.repository;

import cn.teammodel.model.entity.appraise.AppraiseRecord;
import cn.teammodel.model.entity.appraise.AppraiseTreeNode;
import cn.teammodel.model.vo.admin.AppraiseNodeRankVo;
import cn.teammodel.model.vo.admin.RankPo;
import cn.teammodel.model.vo.appraise.AppraiseRecordVo;
import cn.teammodel.model.vo.appraise.RecordVo;
import com.azure.spring.data.cosmos.repository.CosmosRepository;
import com.azure.spring.data.cosmos.repository.Query;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.List;

/**
 * @author winter
 * @create 2023-11-20 14:39 <br/>
 * Page<User> findByLastname(String lastname, Pageable pageable); <br/>
 * Slice<User> findByLastname(String lastname, Pageable pageable);<br/>
 * Window<User> findTop10ByLastname(String lastname, ScrollPosition position, Sort sort);<br/>
 * List<User> findByLastname(String lastname, Sort sort);<br/>
 * List<User> findByLastname(String lastname, Sort sort, Limit limit);<br/>
 * List<User> findByLastname(String lastname, Pageable pageable);<br/>
 */
@Repository
public interface AppraiseRecordRepository extends CosmosRepository<AppraiseRecord, String> {
    /**
    * 查询评价记录
    */
    AppraiseRecord findAppraiseRecordByTargetIdAndClassIdAndAcademicYearIdAndCode(String targetId, String classId, String academicYearId, String code);
    @Query("select c.id, c.praiseCount, c.score from Student as c where c.targetId = @targetId and c.academicYearId = @academicYearId and c.code = @code")
    List<AppraiseRecord> findScoreAndPraise(String targetId,String academicYearId,String code);

    @Query("select * from Student as c where c.targetId in (@targetId) and c.classId in(@classId) and c.academicYearId = @academicYearId and c.code = @code")
    List<AppraiseRecord> findAllRecord(List<String> targetId,List<String> classId,String academicYearId,String code);

    /**
    * 条件查询
    */
    @Query("select Student.id as recordId, Student.name, Student.avatar, Student.targetId, Student.targetType, n as info from Student join n in Student.nodes where " +
            "(IS_NULL(@targetId) or Student.targetId = @targetId) and " +
            "(IS_NULL(@targetType) or Student.targetType = @targetType) and " +
            "(IS_NULL(@classId) or Student.classId = @classId) and " +
            "(IS_NULL(@creatorId) or n.creatorId = @creatorId) and " +
            "(IS_NULL(@academicYearId) or Student.academicYearId = @academicYearId) and " +
            "(IS_NULL(@isPraise) or n.appraiseNode.isPraise = @isPraise) and " +
            "Student.code = @code")
    List<AppraiseRecordVo> searchNodesByCondition(String targetId,
                                                  String targetType,
                                                  String classId,
                                                  String creatorId,
                                                  String academicYearId,
                                                  Boolean isPraise,
                                                  String code);

    /**
    * 查询学校的评价总数, praise = null 时查询总数,否则查询当前学段对应是否表扬的评价总数
    */
    @Query("select value count(1) from Student as c join n in c.nodes where c.code = @code and" +
            " (IS_NULL(@praise) or n.appraiseNode.isPraise = @praise)")
    int countRecords(Boolean praise, String academicYearId, String code);


    @Query("select c.targetId, c.targetType, n.createTime, n.appraiseNode.isPraise, n.creatorId from Student as c join n in c.nodes where c.code = @code and c.academicYearId =  @academicYearId")
    Slice<RecordVo> findAllByAcademicYearId(String code, String academicYearId, Pageable pageable);

    /**
    * 最新的评价明细,分页
    */
    @Query("select c.id as recordId, c.name as targetName, c.avatar, c.classId,c.className, n.id as recordNodeId, c.targetId, c.targetType, n.creator, n.createTime, n.appraiseNode.name as appraiseName, n.appraiseNode.isPraise, n.device ,n.appraiseNode.path from Student as c join n in c.nodes where " +
            "c.code = @code and " +
            "c.academicYearId =  @academicYearId and " +
            "(IS_NULL(@startTime) or n.createTime >= @startTime) and " +
            "(IS_NULL(@endTime) or n.createTime <= @endTime) and " +
            "(IS_NULL(@typeName) or array_contains(n.appraiseNode.path ,@typeName)) and " +
            "c.classId in (@ids) "

    )
    List<RecordVo> latestRecords(String code, String academicYearId, Long startTime, Long endTime,String typeName, Collection<String> ids);


    /**
     * 获取指定学生的评价记录
     */
    @Query("select c.id as recordId, c.name as targetName, c.avatar, c.classId,c.className, n.id as recordNodeId, c.targetId, c.targetType, n.creator, n.createTime, n.appraiseNode.name as appraiseName, n.appraiseNode.isPraise, n.device,n.appraiseNode.path from Student as c join n in c.nodes where " +
            "c.code = @code and " +
            "c.academicYearId =  @academicYearId and " +
            "c.targetId = @studentId and " +
            "(IS_NULL(@startTime) or n.createTime >= @startTime) and " +
            "(IS_NULL(@endTime) or n.createTime <= @endTime) and " +
            "(IS_NULL(@typeName) or array_contains(n.appraiseNode.path ,@typeName)) "
    )
    List<RecordVo> getStudentRecords(String code,String academicYearId ,String studentId, Long startTime, Long endTime,String typeName);


    @Query("select c.id as recordId, c.name as targetName, c.avatar, c.classId,c.className, n.id as recordNodeId, c.targetId, c.targetType, n.creator, n.createTime, n.appraiseNode.name as appraiseName, n.appraiseNode.isPraise, n.device,n.appraiseNode.path from Student as c join n in c.nodes where " +
            "c.code = @code and " +
            "c.academicYearId =  @academicYearId and " +
            "c.classId = @classId and " +
            "(IS_NULL(@studentId) or c.targetId = @studentId) and " +
            "(IS_NULL(@typeName) or array_contains(n.appraiseNode.path ,@typeName)) "
    )
    List<RecordVo> getRecords(String code, String academicYearId, String classId,String studentId,String typeName);


    @Query("select c.classId as id, count(1) as count from Student as c join n in c.nodes where( " +
            "c.code = @code) and " +
            "(c.academicYearId = @academicYearId) and " +
            "(IS_NULL(@startTime) or n.createTime >= @startTime) and " +
            "(IS_NULL(@endTime) or n.createTime <= @endTime) " +
            "group by c.classId")
    List<RankPo> classRank(String code, String academicYearId, Long startTime, Long endTime);

    @Query("select n.creatorId as id, n.appraiseNode.isPraise, count(1) as count from Student as c join n in c.nodes where " +
            "(c.academicYearId = @academicYearId) and " +
            "(IS_NULL(@startTime) or n.createTime >= @startTime) and " +
            "(IS_NULL(@endTime) or n.createTime <= @endTime) and " +
            "(c.code = @code) " +
            "group by n.creatorId, n.appraiseNode.isPraise")
    List<RankPo> teacherRank(String code, String academicYearId, Long startTime, Long endTime);

    @Query("select n.appraiseNode.name as name, count(1) as count from Student as c join n in c.nodes where " +
            "(c.academicYearId = @academicYearId) and " +
            "(IS_NULL(@startTime) or n.createTime >= @startTime) and " +
            "(IS_NULL(@endTime) or n.createTime <= @endTime) and " +
            "(c.code = @code) " +
            "group by n.appraiseNode.name")
    List<AppraiseNodeRankVo> appraiseNodeRank(String code, String academicYearId, Long startTime, Long endTime);

    @Query("select DISTINCT n.appraiseNode.name, n.appraiseNode.path, n.appraiseNode.isPraise from Student as c join n in c.nodes where " +
            "            (c.academicYearId = @academicYearId) and " +
            "            (c.code = @code) and " +
            "            n.appraiseNode.name in (@names)")
    List<AppraiseTreeNode> findAppraiseRecordInNames(String code, String academicYearId, List<String> names);

    /**
    * 仅针对学生,不包括班级评价
    */
    @Query("select c.targetId as id, n.appraiseNode.isPraise, count(1) as count from Student as c join n in c.nodes where " +
            "(c.academicYearId = @academicYearId) and " +
            "(IS_NULL(@startTime) or n.createTime >= @startTime) and " +
            "(IS_NULL(@endTime) or n.createTime <= @endTime) and " +
            "(c.targetType = 'student') and " +
            "(c.code = @code) " +
            "group by c.targetId, n.appraiseNode.isPraise")
    List<RankPo> studentRank(String code, String academicYearId, Long startTime, Long endTime);

    @Query("SELECT value count(1) FROM Student AS c where c.code = @code and c.academicYearId = @academicYearId and c.classId = @classId and c.praiseCount > @praiseCount")
    int findClassRecord(String code, String academicYearId, String classId, int praiseCount);



    // test script
    @Query("select * from Student as c where c.code = @code")
    List<AppraiseRecord> findByCode(String code);
}
