package cn.novalon.gym.manage.member.repository;

import cn.novalon.gym.manage.member.entity.MemberCard;
import org.springframework.data.domain.Pageable;
import org.springframework.data.r2dbc.repository.Modifying;
import org.springframework.data.r2dbc.repository.Query;
import org.springframework.data.r2dbc.repository.R2dbcRepository;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * 会员卡类型 Repository
 * 
 * @author 付嘉
 * @date 2026-05-27
 */
@Repository
public interface MemberCardRepository extends R2dbcRepository<MemberCard, Long> {

    /**
     * 根据会员卡ID查询（未删除的）
     */
    Mono<MemberCard> findByMemberCardIdAndDeletedAtIsNull(Long memberCardId);

    /**
     * 条件查询会员卡列表
     */
    @Query("SELECT * FROM member_card WHERE deleted_at IS NULL " +
            "AND (:status IS NULL OR member_card_status = :status) " +
            "AND (:name IS NULL OR member_card_name LIKE CONCAT('%', :name, '%')) " +
            "AND (:type IS NULL OR member_card_type = :type) " +
            "AND (:minPrice IS NULL OR member_card_price >= :minPrice) " +
            "AND (:maxPrice IS NULL OR member_card_price <= :maxPrice) " +
            "ORDER BY created_at DESC LIMIT :#{#pageable.pageSize} OFFSET :#{#pageable.offset}")
    Flux<MemberCard> findWithConditions(Integer status, String name, String type,
                                        Double minPrice, Double maxPrice, Pageable pageable);

    /**
     * 统计符合条件的会员卡总数
     */
    @Query("SELECT COUNT(*) FROM member_card WHERE deleted_at IS NULL " +
            "AND (:status IS NULL OR member_card_status = :status) " +
            "AND (:name IS NULL OR member_card_name LIKE CONCAT('%', :name, '%')) " +
            "AND (:type IS NULL OR member_card_type = :type) " +
            "AND (:minPrice IS NULL OR member_card_price >= :minPrice) " +
            "AND (:maxPrice IS NULL OR member_card_price <= :maxPrice)")
    Mono<Long> countWithConditions(Integer status, String name, String type,
                                   Double minPrice, Double maxPrice);

    /**
     * 按状态查询会员卡列表
     */
    Flux<MemberCard> findByMemberCardStatusAndDeletedAtIsNull(Integer status, Pageable pageable);

    /**
     * 检查会员卡是否已被购买
     */
    @Query("SELECT EXISTS(SELECT 1 FROM member_card_record WHERE member_card_id = :memberCardId AND deleted_at IS NULL LIMIT 1)")
    Mono<Boolean> existsPurchasedRecord(Long memberCardId);

    /**
     * 逻辑删除会员卡
     */
    @Modifying
    @Query("UPDATE member_card SET deleted_at = NOW() WHERE member_card_id = :memberCardId AND deleted_at IS NULL")
    Mono<Integer> logicalDelete(Long memberCardId);

    /**
     * 安全更新会员卡信息
     */
    @Modifying
    @Query("UPDATE member_card SET " +
            "member_card_name = COALESCE(:name, member_card_name), " +
            "member_card_price = COALESCE(:price, member_card_price), " +
            "member_card_validity_days = COALESCE(:durationDays, member_card_validity_days), " +
            "member_card_total_times = COALESCE(:totalCount, member_card_total_times), " +
            "member_card_amount = COALESCE(:denomination, member_card_amount), " +
            "member_card_status = COALESCE(:status, member_card_status), " +
            "updated_at = NOW() " +
            "WHERE member_card_id = :memberCardId AND deleted_at IS NULL")
    Mono<Integer> updateSafe(Long memberCardId, String name, Double price,
                             Integer durationDays, Integer totalCount,
                             Double denomination, Integer status);

    /**
     * 批量查询上架的会员卡
     */
    @Query("SELECT * FROM member_card WHERE deleted_at IS NULL AND member_card_status = :status ORDER BY member_card_price ASC")
    Flux<MemberCard> findActiveCards(Integer status);
}
