package com.zioinfo.kintex.webhook;

import com.zioinfo.kintex.webhook.automation.FollowupMapper;
import com.zioinfo.kintex.webhook.automation.LeadFollowupAutomation;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

/**
 * F052 팔로업 EDM 자동 트리거 멱등성 단위테스트(FollowupMapper 모킹).
 */
class LeadFollowupAutomationTest {

    private Map<String, Object> lead(String id, String eventId, int score) {
        return Map.of("leadId", id, "eventId", eventId, "score", score,
                "company", "(주)테크솔루션", "product", "협동로봇", "bodyDraft", "draft body");
    }

    @Test
    void createsOneCampaignPerReservedHotLead() {
        FollowupMapper mapper = mock(FollowupMapper.class);
        when(mapper.findUnprocessedHotLeads(anyInt()))
                .thenReturn(List.of(lead("ld-1", "e-1", 87), lead("ld-2", "e-1", 82)));
        // 둘 다 예약 성공(신규).
        when(mapper.reserveFollowup(anyString(), anyString(), anyString(), anyInt(), any()))
                .thenReturn(1);

        LeadFollowupAutomation auto = new LeadFollowupAutomation(mapper);
        int created = auto.sweepOnce();

        assertEquals(2, created, "hot 리드 2건 → 캠페인 초안 2건");
        verify(mapper, times(2)).insertFollowupCampaign(anyString(), anyString(), anyString(), anyString());
        verify(mapper, times(2)).linkCampaign(anyString(), anyString());
    }

    @Test
    void idempotentSkipsAlreadyProcessedLead() {
        FollowupMapper mapper = mock(FollowupMapper.class);
        when(mapper.findUnprocessedHotLeads(anyInt()))
                .thenReturn(List.of(lead("ld-1", "e-1", 90)));
        // 이미 처리됨 — 로그 예약 충돌(0) → 캠페인 생성 금지.
        when(mapper.reserveFollowup(anyString(), eq("e-1"), eq("ld-1"), anyInt(), any()))
                .thenReturn(0);

        LeadFollowupAutomation auto = new LeadFollowupAutomation(mapper);
        int created = auto.sweepOnce();

        assertEquals(0, created, "예약 충돌 시 캠페인 미생성(멱등)");
        verify(mapper, never()).insertFollowupCampaign(anyString(), anyString(), anyString(), anyString());
        verify(mapper, never()).linkCampaign(anyString(), anyString());
    }

    @Test
    void noCandidatesProducesNoCampaign() {
        FollowupMapper mapper = mock(FollowupMapper.class);
        when(mapper.findUnprocessedHotLeads(anyInt())).thenReturn(List.of());

        LeadFollowupAutomation auto = new LeadFollowupAutomation(mapper);
        assertEquals(0, auto.sweepOnce());
        verify(mapper, never()).reserveFollowup(anyString(), anyString(), anyString(), anyInt(), any());
    }
}
