package cn.novalon.gym.manage.member.service.impl;

import cn.novalon.gym.manage.member.entity.MemberCardTransaction;
import cn.novalon.gym.manage.member.enums.TransactionType;
import cn.novalon.gym.manage.member.repository.MemberCardTransactionRepository;
import cn.novalon.gym.manage.member.service.IMemberCardTransactionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;

/**
 * 会员卡交易流水服务实现
 * 
 * @author 付嘉
 * @date 2026-05-27
 */
@Slf4j
@Service
public class MemberCardTransactionServiceImpl implements IMemberCardTransactionService {
    private final MemberCardTransactionRepository transactionRepository;

    public MemberCardTransactionServiceImpl(MemberCardTransactionRepository transactionRepository) {
        this.transactionRepository = transactionRepository;
    }

    @Override
    public Mono<MemberCardTransaction> insertTransaction(MemberCardTransaction transaction) {
        return transactionRepository.insertTransaction(
                transaction.getMemberCardRecordId(),
                transaction.getMemberCardId(),
                transaction.getMemberId(),
                transaction.getOperationType(),
                transaction.getChangeAmount(),
                transaction.getChangeBalance(),
                transaction.getAfterRemainingCount(),
                transaction.getAfterRemainingBalance(),
                transaction.getRelatedBizType(),
                transaction.getSourceOrderId(),
                transaction.getRemark()
        );
    }

    @Override
    public Flux<MemberCardTransaction> findByMemberIdAndTimeRange(Long memberId, LocalDateTime startTime,
                                                                   LocalDateTime endTime, Pageable pageable) {
        return transactionRepository.findByMemberIdAndTimeRange(memberId, startTime, endTime, pageable);
    }

    @Override
    public Flux<MemberCardTransaction> findWithConditions(Long memberId, Long memberCardId,
                                                          TransactionType operationType,
                                                          LocalDateTime startTime, LocalDateTime endTime,
                                                          Pageable pageable) {
        return transactionRepository.findWithConditions(memberId, memberCardId, 
                operationType != null ? operationType.name() : null,
                startTime, endTime, pageable);
    }

    @Override
    public Mono<Long> countWithConditions(Long memberId, Long memberCardId,
                                          TransactionType operationType,
                                          LocalDateTime startTime, LocalDateTime endTime) {
        return transactionRepository.countWithConditions(memberId, memberCardId,
                operationType != null ? operationType.name() : null,
                startTime, endTime);
    }

    @Override
    public Flux<MemberCardTransaction> findByMemberCardId(Long memberCardId) {
        return transactionRepository.findByMemberCardId(memberCardId);
    }

    @Override
    public Mono<Long> sumDeductCountByCardId(Long memberCardId, LocalDateTime startTime, LocalDateTime endTime) {
        return transactionRepository.sumDeductCountByCardId(memberCardId, startTime, endTime);
    }

    @Override
    public Mono<Double> sumRenewAmountByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
        return transactionRepository.sumRenewAmountByTimeRange(startTime, endTime);
    }

    @Override
    public Mono<Double> sumPurchaseAmountByMemberId(Long memberId, LocalDateTime startTime, LocalDateTime endTime) {
        return transactionRepository.sumPurchaseAmountByMemberId(memberId, startTime, endTime);
    }

    @Override
    public Mono<Void> createTransaction(MemberCardTransaction transaction) {
        return transactionRepository.save(transaction)
                .then()
                .doOnSuccess(v -> log.info("创建会员卡交易记录: memberId={}, cardId={}, type={}",
                        transaction.getMemberId(), transaction.getMemberCardId(), transaction.getOperationType()));
    }

    @Override
    public Flux<MemberCardTransaction> findByMemberId(Long memberId) {
        return transactionRepository.findByMemberId(memberId);
    }

    @Override
    public Flux<MemberCardTransaction> findByRecordId(Long recordId) {
        return transactionRepository.findByRecordId(recordId);
    }
}
