package incheon.product.common.theme.web;

import incheon.product.common.theme.service.CommonThemeService;
import incheon.product.common.theme.vo.ThemeCategoryVO;
import incheon.product.common.theme.vo.ThemeLayerVO;
import incheon.product.common.theme.vo.ThemeVO;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
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 org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import java.util.List;

import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;

/**
 * CommonThemeViewController MockMvc 테스트.
 * dim별 뷰 라우팅, 유효하지 않은 dim → 404, 모델 속성 바인딩을 검증한다.
 */
@ExtendWith(MockitoExtension.class)
class CommonThemeViewControllerTest {

    @InjectMocks
    private CommonThemeViewController controller;

    @Mock
    private CommonThemeService commonThemeService;

    private MockMvc mockMvc;

    @BeforeEach
    void setup() {
        mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
    }

    @Test
    @DisplayName("dim=g2d → 2D 주제도 뷰")
    void themeViewG2d() throws Exception {
        ThemeVO theme = new ThemeVO();
        theme.setId("T001");
        theme.setName("도시계획");
        when(commonThemeService.getTheme("T001")).thenReturn(theme);
        when(commonThemeService.getCategories()).thenReturn(List.of());
        when(commonThemeService.getLayersByThemeId("T001")).thenReturn(List.of());

        mockMvc.perform(get("/product/g2d/theme/T001.do"))
                .andExpect(status().isOk())
                .andExpect(view().name("product/geoview2d/themeMap"))
                .andExpect(model().attribute("dim", "g2d"))
                .andExpect(model().attribute("pageTitle", "GeoView-2D"))
                .andExpect(model().attribute("headerTitle", "도시계획"));
    }

    @Test
    @DisplayName("dim=g3d → 3D 주제도 뷰")
    void themeViewG3d() throws Exception {
        when(commonThemeService.getTheme("T002")).thenReturn(null);
        when(commonThemeService.getCategories()).thenReturn(List.of());
        when(commonThemeService.getLayersByThemeId("T002")).thenReturn(List.of());

        mockMvc.perform(get("/product/g3d/theme/T002.do"))
                .andExpect(status().isOk())
                .andExpect(view().name("product/geoview3d/map"))
                .andExpect(model().attribute("pageTitle", "GeoView-3D"))
                .andExpect(model().attribute("headerTitle", "주제도"));
    }

    @Test
    @DisplayName("유효하지 않은 dim → error/404 뷰")
    void themeViewInvalidDim() throws Exception {
        mockMvc.perform(get("/product/invalid/theme/T001.do"))
                .andExpect(status().isOk())
                .andExpect(view().name("error/404"));
    }

    @Test
    @DisplayName("모델에 layerMap 속성 바인딩")
    void themeViewPopulatesLayerMap() throws Exception {
        ThemeLayerVO layer = new ThemeLayerVO();
        layer.setLayerId("L001");
        layer.setName("도로");
        when(commonThemeService.getTheme("T001")).thenReturn(new ThemeVO());
        when(commonThemeService.getCategories()).thenReturn(List.of(new ThemeCategoryVO()));
        when(commonThemeService.getLayersByThemeId("T001")).thenReturn(List.of(layer));

        mockMvc.perform(get("/product/g2d/theme/T001.do"))
                .andExpect(status().isOk())
                .andExpect(model().attributeExists("layerMap"))
                .andExpect(model().attributeExists("categories"))
                .andExpect(model().attributeExists("themeLayers"));
    }
}
