package com.example.demo.repository;

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

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.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import com.example.demo.model.UserWork;

/**
 * 用户作品仓库接口
 */
@Repository
public interface UserWorkRepository extends JpaRepository<UserWork, Long> {

    /**
     * 根据用户名查找作品
     */
    @Query("SELECT uw FROM UserWork uw WHERE uw.username = :username AND uw.status != 'DELETED' ORDER BY uw.createdAt DESC")
    Page<UserWork> findByUsernameOrderByCreatedAtDesc(@Param("username") String username, Pageable pageable);

    /**
     * 根据用户名和状态查找作品
     */
    @Query("SELECT uw FROM UserWork uw WHERE uw.username = :username AND uw.status = :status ORDER BY uw.createdAt DESC")
    List<UserWork> findByUsernameAndStatusOrderByCreatedAtDesc(@Param("username") String username, @Param("status") UserWork.WorkStatus status);

    /**
     * 根据任务ID查找作品
     */
    Optional<UserWork> findByTaskId(String taskId);

    /**
     * 根据用户名和任务ID查找作品
     */
    Optional<UserWork> findByUsernameAndTaskId(String username, String taskId);

    /**
     * 查找公开作品
     */
    @Query("SELECT uw FROM UserWork uw WHERE uw.isPublic = true AND uw.status = 'COMPLETED' ORDER BY uw.createdAt DESC")
    Page<UserWork> findPublicWorksOrderByCreatedAtDesc(Pageable pageable);

    /**
     * 根据作品类型查找公开作品
     */
    @Query("SELECT uw FROM UserWork uw WHERE uw.isPublic = true AND uw.status = 'COMPLETED' AND uw.workType = :workType ORDER BY uw.createdAt DESC")
    Page<UserWork> findPublicWorksByTypeOrderByCreatedAtDesc(@Param("workType") UserWork.WorkType workType, Pageable pageable);

    /**
     * 根据标签搜索作品
     */
    @Query("SELECT uw FROM UserWork uw WHERE uw.isPublic = true AND uw.status = 'COMPLETED' AND uw.tags LIKE %:tag% ORDER BY uw.createdAt DESC")
    Page<UserWork> findPublicWorksByTagOrderByCreatedAtDesc(@Param("tag") String tag, Pageable pageable);

    /**
     * 根据提示词搜索作品
     */
    @Query("SELECT uw FROM UserWork uw WHERE uw.isPublic = true AND uw.status = 'COMPLETED' AND uw.prompt LIKE %:keyword% ORDER BY uw.createdAt DESC")
    Page<UserWork> findPublicWorksByPromptOrderByCreatedAtDesc(@Param("keyword") String keyword, Pageable pageable);

    /**
     * 统计用户作品数量
     */
    @Query("SELECT COUNT(uw) FROM UserWork uw WHERE uw.username = :username AND uw.status != 'DELETED'")
    long countByUsername(@Param("username") String username);

    /**
     * 统计用户公开作品数量
     */
    @Query("SELECT COUNT(uw) FROM UserWork uw WHERE uw.username = :username AND uw.isPublic = true AND uw.status = 'COMPLETED'")
    long countPublicWorksByUsername(@Param("username") String username);

    /**
     * 获取热门作品（按浏览次数排序）
     */
    @Query("SELECT uw FROM UserWork uw WHERE uw.isPublic = true AND uw.status = 'COMPLETED' ORDER BY uw.viewCount DESC, uw.createdAt DESC")
    Page<UserWork> findPopularWorksOrderByViewCountDesc(Pageable pageable);

    /**
     * 获取最新作品
     */
    @Query("SELECT uw FROM UserWork uw WHERE uw.isPublic = true AND uw.status = 'COMPLETED' ORDER BY uw.createdAt DESC")
    Page<UserWork> findLatestWorksOrderByCreatedAtDesc(Pageable pageable);

    /**
     * 更新作品状态
     */
    @Modifying
    @Query("UPDATE UserWork uw SET uw.status = :status, uw.updatedAt = :updatedAt, uw.completedAt = :completedAt WHERE uw.taskId = :taskId")
    int updateStatusByTaskId(@Param("taskId") String taskId, 
                           @Param("status") UserWork.WorkStatus status, 
                           @Param("updatedAt") LocalDateTime updatedAt,
                           @Param("completedAt") LocalDateTime completedAt);

    /**
     * 更新作品结果URL
     */
    @Modifying
    @Query("UPDATE UserWork uw SET uw.resultUrl = :resultUrl, uw.updatedAt = :updatedAt WHERE uw.taskId = :taskId")
    int updateResultUrlByTaskId(@Param("taskId") String taskId, 
                               @Param("resultUrl") String resultUrl,
                               @Param("updatedAt") LocalDateTime updatedAt);

    /**
     * 增加浏览次数
     */
    @Modifying
    @Query("UPDATE UserWork uw SET uw.viewCount = uw.viewCount + 1, uw.updatedAt = :updatedAt WHERE uw.id = :id")
    int incrementViewCount(@Param("id") Long id, @Param("updatedAt") LocalDateTime updatedAt);

    /**
     * 增加点赞次数
     */
    @Modifying
    @Query("UPDATE UserWork uw SET uw.likeCount = uw.likeCount + 1, uw.updatedAt = :updatedAt WHERE uw.id = :id")
    int incrementLikeCount(@Param("id") Long id, @Param("updatedAt") LocalDateTime updatedAt);

    /**
     * 增加下载次数
     */
    @Modifying
    @Query("UPDATE UserWork uw SET uw.downloadCount = uw.downloadCount + 1, uw.updatedAt = :updatedAt WHERE uw.id = :id")
    int incrementDownloadCount(@Param("id") Long id, @Param("updatedAt") LocalDateTime updatedAt);

    /**
     * 软删除作品
     */
    @Modifying
    @Query("UPDATE UserWork uw SET uw.status = 'DELETED', uw.updatedAt = :updatedAt WHERE uw.id = :id AND uw.username = :username")
    int softDeleteWork(@Param("id") Long id, @Param("username") String username, @Param("updatedAt") LocalDateTime updatedAt);

    /**
     * 删除过期作品（超过30天且状态为失败）
     */
    @Modifying
    @Query("DELETE FROM UserWork uw WHERE uw.status = 'FAILED' AND uw.createdAt < :expiredDate")
    int deleteExpiredFailedWorks(@Param("expiredDate") LocalDateTime expiredDate);

    /**
     * 获取用户作品统计信息
     */
    @Query("SELECT " +
           "COUNT(CASE WHEN uw.status = 'COMPLETED' THEN 1 END) as completedCount, " +
           "COUNT(CASE WHEN uw.status = 'PROCESSING' THEN 1 END) as processingCount, " +
           "COUNT(CASE WHEN uw.status = 'FAILED' THEN 1 END) as failedCount, " +
           "SUM(CASE WHEN uw.status = 'COMPLETED' THEN uw.pointsCost ELSE 0 END) as totalPointsCost " +
           "FROM UserWork uw WHERE uw.username = :username AND uw.status != 'DELETED'")
    Object[] getUserWorkStats(@Param("username") String username);
}


