package com.ruoyi.system.omgpay.mapper;

import com.ruoyi.system.omgpay.domain.OmgPaymentAttempt;
import com.ruoyi.system.omgpay.domain.OmgPaymentOrderSnapshot;
import org.apache.ibatis.annotations.Param;

import java.util.Date;
import java.util.List;

/**
 * Persistence boundary for locking order facts and appending OMG payment attempts.
 */
public interface OmgPaymentAttemptMapper {
    OmgPaymentOrderSnapshot selectOrderForUpdate(@Param("ddId") String ddId);

    /** Read-only ownership snapshot used before calling the OMG query API. */
    OmgPaymentOrderSnapshot selectOrder(@Param("ddId") String ddId);

    /** Current read used both before creation and after an active-order unique-key conflict. */
    OmgPaymentAttempt selectActiveCreatedByDdIdForUpdate(@Param("ddId") String ddId);

    /** The single current unpaid attempt eligible for a user-triggered query. */
    OmgPaymentAttempt selectActiveCreatedByDdId(@Param("ddId") String ddId);

    /** The first paid fact for an already-paid order; payment facts are irreversible. */
    OmgPaymentAttempt selectPaidByDdId(@Param("ddId") String ddId);

    /** Current read used after an insert conflict to classify a committed trade-number collision. */
    OmgPaymentAttempt selectByMerchantTradeNoForUpdate(@Param("merchantTradeNo") String merchantTradeNo);

    /** Preliminary read used to discover the order before locks are acquired in order-first sequence. */
    OmgPaymentAttempt selectByMerchantTradeNo(@Param("merchantTradeNo") String merchantTradeNo);

    /** CREATED attempts whose next automatic query is due, ordered fairly by due time. */
    List<OmgPaymentAttempt> selectDueCreated(@Param("now") Date now, @Param("limit") int limit);

    /** Atomically reserves one due attempt and advances its next query time. */
    int reserveDueQuery(@Param("id") Long id, @Param("now") Date now,
                        @Param("nextQueryTime") Date nextQueryTime);

    int insertCreated(OmgPaymentAttempt row);

    int markPaid(OmgPaymentAttempt row);

    int markFailed(OmgPaymentAttempt row);

    /** Closes exactly one still-active attempt before a verified user retry. */
    int supersedeCreated(@Param("id") Long id, @Param("updateTime") Date updateTime);

    int supersedeOtherCreated(@Param("ddId") String ddId, @Param("paidAttemptId") Long paidAttemptId,
                              @Param("updateTime") Date updateTime);

    int markOrderPaid(@Param("ddId") String ddId);

    int countOtherPaidAttempts(@Param("ddId") String ddId, @Param("attemptId") Long attemptId);
}
