package com.zioinfo.kintex.dashboard;

import com.zioinfo.kintex.common.error.ApiException;
import com.zioinfo.kintex.common.error.ErrorCode;
import com.zioinfo.kintex.dashboard.dto.DashboardDto;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

/**
 * 대시보드 서비스 단위테스트 — 마일스톤 파생(과거=done)·KPI 조립·미존재 행사 404.
 */
class DashboardServiceTest {

    private DashboardMapper mapper;
    private DashboardService service;

    @BeforeEach
    void setUp() {
        mapper = mock(DashboardMapper.class);
        service = new DashboardService(mapper);
    }

    @Test
    void throwsNotFoundWhenEventMissing() {
        when(mapper.findEventHeader("x")).thenReturn(null);
        ApiException ex = assertThrows(ApiException.class, () -> service.getDashboard("x"));
        assertEquals(ErrorCode.NOT_FOUND, ex.getCode());
    }

    @Test
    void derivesMilestonesAndKpisFromRealCounts() {
        // 미래 시작일 → 개장 upcoming, 먼 과거 파생일(D-150 등)은 done.
        String futureStart = LocalDate.now().plusDays(10).toString();
        Map<String, Object> header = new HashMap<>();
        header.put("startDate", futureStart);
        when(mapper.findEventHeader("e1")).thenReturn(header);

        Map<String, Object> counts = new HashMap<>();
        counts.put("boothCount", 12);
        counts.put("targetBooths", 20);
        counts.put("designApproved", 3);
        counts.put("designTotal", 8);
        counts.put("utilityOrders", 5);
        counts.put("renderDone", 7);
        when(mapper.findKpiCounts("e1")).thenReturn(counts);
        when(mapper.findExhibitors("e1")).thenReturn(List.of());
        when(mapper.findRecentRenders("e1")).thenReturn(List.of());

        DashboardDto dto = service.getDashboard("e1");

        // 마일스톤 5종, 개장(D-0)은 미래 → upcoming.
        assertEquals(5, dto.milestones().size());
        DashboardDto.Milestone opening = dto.milestones().get(dto.milestones().size() - 1);
        assertEquals("개장", opening.label());
        assertEquals("upcoming", opening.state());
        // 초기 D-150 파생일은 과거 → done.
        assertEquals("done", dto.milestones().get(0).state());

        // KPI: 부스 배치 "12/20".
        assertTrue(dto.kpis().stream().anyMatch(k -> "부스 배치".equals(k.label()) && "12/20".equals(k.value())));
        assertTrue(dto.kpis().stream().anyMatch(k -> "설계 승인".equals(k.label()) && "3/8".equals(k.value())));
    }
}
