package dev.lions.unionflow.server.payment;

import dev.lions.unionflow.server.api.payment.PaymentEvent;
import dev.lions.unionflow.server.api.payment.PaymentStatus;
import dev.lions.unionflow.server.payment.orchestration.PaymentOrchestrator;
import dev.lions.unionflow.server.payment.orchestration.PaymentProviderRegistry;
import dev.lions.unionflow.server.service.PaiementService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.math.BigDecimal;
import java.time.Instant;

import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class PaymentOrchestratorHandleEventTest {

    @Mock
    PaymentProviderRegistry registry;

    @Mock
    PaiementService paiementService;

    @InjectMocks
    PaymentOrchestrator orchestrator;

    @BeforeEach
    void setup() throws Exception {
        // Inject default config values via reflection
        var defaultProviderField = PaymentOrchestrator.class.getDeclaredField("defaultProvider");
        defaultProviderField.setAccessible(true);
        defaultProviderField.set(orchestrator, "WAVE");

        var pispiField = PaymentOrchestrator.class.getDeclaredField("pispiPriority");
        pispiField.setAccessible(true);
        pispiField.set(orchestrator, false);
    }

    @Test
    void handleEvent_delegatesToPaiementService() {
        PaymentEvent event = new PaymentEvent(
                "ext-123", "PAY-REF-001", PaymentStatus.SUCCESS,
                BigDecimal.valueOf(5000), "TXN-ABC", Instant.now());

        orchestrator.handleEvent(event);

        verify(paiementService).mettreAJourStatutDepuisWebhook(event);
    }

    @Test
    void handleEvent_withFailedStatus_delegatesToPaiementService() {
        PaymentEvent event = new PaymentEvent(
                "ext-456", "PAY-REF-002", PaymentStatus.FAILED,
                BigDecimal.ZERO, null, Instant.now());

        orchestrator.handleEvent(event);

        verify(paiementService).mettreAJourStatutDepuisWebhook(event);
    }

    @Test
    void handleEvent_withCancelledStatus_delegatesToPaiementService() {
        PaymentEvent event = new PaymentEvent(
                "ext-789", "PAY-REF-003", PaymentStatus.CANCELLED,
                BigDecimal.ZERO, null, Instant.now());

        orchestrator.handleEvent(event);

        verify(paiementService).mettreAJourStatutDepuisWebhook(event);
    }
}
