package com.mosquito.project.persistence.repository;

import com.mosquito.project.persistence.entity.SysAuditLogEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 审计日志 Repository
 */
@Repository
public interface SysAuditLogRepository extends JpaRepository<SysAuditLogEntity, Long> {

    /**
     * 根据关键词搜索审计日志
     */
    @Query("SELECT a FROM SysAuditLogEntity a WHERE " +
           "(:keyword IS NULL OR :keyword = '' OR " +
           "a.operation LIKE %:keyword% OR " +
           "a.resourceType LIKE %:keyword% OR " +
           "a.resourceId LIKE %:keyword% OR " +
           "a.operationDetails LIKE %:keyword% OR " +
           "a.userName LIKE %:keyword%)")
    Page<SysAuditLogEntity> searchByKeyword(@Param("keyword") String keyword, Pageable pageable);

    /**
     * 综合查询：支持module(operation)、user和keyword过滤
     */
    @Query("SELECT a FROM SysAuditLogEntity a WHERE " +
           "(:keyword IS NULL OR :keyword = '' OR " +
           "a.operation LIKE %:keyword% OR " +
           "a.resourceType LIKE %:keyword% OR " +
           "a.resourceId LIKE %:keyword% OR " +
           "a.operationDetails LIKE %:keyword% OR " +
           "a.userName LIKE %:keyword%) " +
           "AND (:operation IS NULL OR :operation = '' OR a.operation = :operation) " +
           "AND (:module IS NULL OR :module = '' OR a.resourceType = :module) " +
           "AND (:userId IS NULL OR a.userId = :userId)")
    Page<SysAuditLogEntity> searchWithFilters(
            @Param("keyword") String keyword,
            @Param("operation") String operation,
            @Param("module") String module,
            @Param("userId") Long userId,
            Pageable pageable);

    /**
     * 根据操作类型查询
     */
    List<SysAuditLogEntity> findByOperation(String operation);

    /**
     * 根据用户ID查询
     */
    List<SysAuditLogEntity> findByUserId(Long userId);

    /**
     * 根据时间范围查询
     */
    List<SysAuditLogEntity> findByCreatedAtBetween(LocalDateTime start, LocalDateTime end);

    /**
     * 统计操作次数
     */
    long countByOperation(String operation);

    /**
     * 统计总数
     */
    long count();

    /**
     * 统计指定时间范围内的总数
     */
    long countByCreatedAtBetween(LocalDateTime start, LocalDateTime end);

    /**
     * 按操作类型统计数量
     */
    @Query("SELECT a.operation, COUNT(a) FROM SysAuditLogEntity a WHERE a.createdAt BETWEEN :start AND :end GROUP BY a.operation")
    List<Object[]> countByOperationGrouped(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end);

    /**
     * 按用户统计数量
     */
    @Query("SELECT a.userId, a.userName, COUNT(a) FROM SysAuditLogEntity a WHERE a.createdAt BETWEEN :start AND :end GROUP BY a.userId, a.userName ORDER BY COUNT(a) DESC")
    List<Object[]> countByUserGrouped(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end);

    /**
     * 按日期统计数量
     */
    @Query("SELECT FUNCTION('DATE', a.createdAt), COUNT(a) FROM SysAuditLogEntity a WHERE a.createdAt BETWEEN :start AND :end GROUP BY FUNCTION('DATE', a.createdAt) ORDER BY FUNCTION('DATE', a.createdAt)")
    List<Object[]> countByDateGrouped(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end);

    /**
     * 获取最新的一条审计日志（按序列号）
     */
    Optional<SysAuditLogEntity> findTopByOrderBySequenceNumDesc();

    /**
     * 获取最大序列号（用于服务重启后序列号初始化）
     * PRD修复: 避免服务重启后序列号回退
     */
    @Query("SELECT MAX(a.sequenceNum) FROM SysAuditLogEntity a")
    Long findMaxSequenceNum();

    /**
     * 综合查询：支持module(operation)、user和keyword过滤，并带数据权限过滤
     */
    @Query("SELECT a FROM SysAuditLogEntity a WHERE " +
           "(:keyword IS NULL OR :keyword = '' OR " +
           "a.operation LIKE %:keyword% OR " +
           "a.resourceType LIKE %:keyword% OR " +
           "a.resourceId LIKE %:keyword% OR " +
           "a.operationDetails LIKE %:keyword% OR " +
           "a.userName LIKE %:keyword%) " +
           "AND (:operation IS NULL OR :operation = '' OR a.operation = :operation) " +
           "AND (:module IS NULL OR :module = '' OR a.resourceType = :module) " +
           "AND (:userId IS NULL OR a.userId = :userId) " +
           "AND (:dataScope = 'ALL' OR " +
           "(:dataScope = 'DEPARTMENT' AND a.departmentId IN :deptIds) OR " +
           "(:dataScope = 'OWN' AND a.userId = :currentUserId))")
    Page<SysAuditLogEntity> searchWithFiltersAndDataScope(
            @Param("keyword") String keyword,
            @Param("operation") String operation,
            @Param("module") String module,
            @Param("userId") Long userId,
            @Param("dataScope") String dataScope,
            @Param("deptIds") List<Long> deptIds,
            @Param("currentUserId") Long currentUserId,
            Pageable pageable);

    /**
     * 支持时间范围、用户ID和数据权限的过滤查询（用于导出和报表）
     */
    @Query("SELECT a FROM SysAuditLogEntity a WHERE " +
           "(:start IS NULL OR a.createdAt >= :start) " +
           "AND (:end IS NULL OR a.createdAt <= :end) " +
           "AND (:operation IS NULL OR :operation = '' OR a.operation = :operation) " +
           "AND (:userId IS NULL OR a.userId = :userId) " +
           "AND (:dataScope = 'ALL' OR " +
           "(:dataScope = 'DEPARTMENT' AND a.departmentId IN :deptIds) OR " +
           "(:dataScope = 'OWN' AND a.userId = :currentUserId))")
    List<SysAuditLogEntity> findWithTimeRangeAndDataScope(
            @Param("start") LocalDateTime start,
            @Param("end") LocalDateTime end,
            @Param("operation") String operation,
            @Param("userId") Long userId,
            @Param("dataScope") String dataScope,
            @Param("deptIds") List<Long> deptIds,
            @Param("currentUserId") Long currentUserId);
}
