package com.sino.mci.inbound.webhook;

import com.sino.mci.inbound.entity.MessageEvent;
import com.sino.mci.inbound.intent.IntentResult;
import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;

class WebhookPayloadBuilderTest {

    private final WebhookPayloadBuilder builder = new WebhookPayloadBuilder();

    @Test
    void shouldBuildPayloadWithAllStandardFields() {
        MessageEvent event = createEvent();
        IntentResult intent = new IntentResult("create_order", 0.95,
                Map.of("customer_name", "张三", "address", "北京"),
                List.of("phone"), true);

        Map<String, Object> payload = builder.buildPayload(event, intent);

        assertThat(payload).containsEntry("event_id", "evt_20260707_001")
                .containsEntry("tenant_code", "rescue")
                .containsEntry("channel_type", "wecom")
                .containsEntry("direction", "in")
                .containsEntry("event_type", "message")
                .containsEntry("conversation_id", 1001L)
                .containsEntry("person_id", 2001L)
                .containsEntry("account_id", 3001L)
                .containsEntry("create_time", "2026-07-03T12:00:00");

        assertThat(payload).containsKey("content");
        @SuppressWarnings("unchecked")
        Map<String, Object> content = (Map<String, Object>) payload.get("content");
        assertThat(content).containsEntry("type", "text")
                .containsEntry("body", "我要下单");

        assertThat(payload).containsKey("intent");
        @SuppressWarnings("unchecked")
        Map<String, Object> intentMap = (Map<String, Object>) payload.get("intent");
        assertThat(intentMap).containsEntry("intent", "create_order")
                .containsEntry("confidence", 0.95)
                .containsEntry("requires_confirmation", true);
        @SuppressWarnings("unchecked")
        Map<String, Object> slots = (Map<String, Object>) intentMap.get("slots");
        assertThat(slots).containsEntry("customer_name", "张三")
                .containsEntry("address", "北京");
        @SuppressWarnings("unchecked")
        List<String> missingSlots = (List<String>) intentMap.get("missing_slots");
        assertThat(missingSlots).containsExactly("phone");

        assertThat(payload).containsKey("business_context");
        @SuppressWarnings("unchecked")
        Map<String, Object> businessContext = (Map<String, Object>) payload.get("business_context");
        assertThat(businessContext).containsEntry("contract_id", "C001");

        assertThat(payload).containsKey("raw_payload");
    }

    @Test
    void shouldMapOutboundDirection() {
        MessageEvent event = createEvent();
        event.setDirection(2);

        Map<String, Object> payload = builder.buildPayload(event, unknownIntent());

        assertThat(payload).containsEntry("direction", "out");
    }

    @Test
    void shouldHandleNullIntent() {
        MessageEvent event = createEvent();

        Map<String, Object> payload = builder.buildPayload(event, null);

        assertThat(payload).containsEntry("intent", null);
    }

    @Test
    void shouldHandleBlankJsonFields() {
        MessageEvent event = createEvent();
        event.setContent(null);
        event.setBusinessContext("");
        event.setRawPayload(null);

        Map<String, Object> payload = builder.buildPayload(event, unknownIntent());

        assertThat(payload).containsEntry("content", null);
        assertThat(payload).containsEntry("business_context", null);
        assertThat(payload).containsEntry("raw_payload", null);
    }

    private MessageEvent createEvent() {
        MessageEvent event = new MessageEvent();
        event.setEventId("evt_20260707_001");
        event.setTenantCode("rescue");
        event.setChannelType("wecom");
        event.setDirection(1);
        event.setEventType("message");
        event.setConversationId(1001L);
        event.setPersonId(2001L);
        event.setAccountId(3001L);
        event.setContent("{\"type\":\"text\",\"body\":\"我要下单\"}");
        event.setRawPayload("{\"seq\":12345}");
        event.setBusinessContext("{\"contract_id\":\"C001\"}");
        event.setCreateTime(LocalDateTime.of(2026, 7, 3, 12, 0, 0));
        return event;
    }

    private IntentResult unknownIntent() {
        return new IntentResult("unknown", 0.0, Map.of(), List.of(), false);
    }
}
