package com.owrawww.controller;

import com.owrawww.domain.Bbs;
import com.owrawww.service.BbsService;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.transaction.TransactionFactory;
import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;

import java.util.List;

import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@Import(HomeControllerTest.MybatisTestConfig.class)
@WebMvcTest(value = HomeController.class, excludeAutoConfiguration = MybatisAutoConfiguration.class)
class HomeControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockitoBean
    private BbsService bbsService;

    @Test
    @DisplayName("GET / - 메인 페이지 정상 응답")
    void index_returnsIndexView() throws Exception {
        Bbs bbs = new Bbs();
        bbs.setId(1L);
        bbs.setTitle("공지사항");

        given(bbsService.getPreview(anyInt(), anyInt(), anyInt(), anyInt()))
                .willReturn(List.of(bbs));

        mockMvc.perform(get("/"))
                .andExpect(status().isOk())
                .andExpect(view().name("index"))
                .andExpect(model().attributeExists("progressList"))
                .andExpect(model().attributeExists("pressList"));
    }

    @Test
    @DisplayName("GET /sitemap - 사이트맵 뷰 반환")
    void sitemap_returnsSitemapView() throws Exception {
        mockMvc.perform(get("/sitemap"))
                .andExpect(status().isOk())
                .andExpect(view().name("sitemap"));
    }

    @Test
    @DisplayName("GET /company/intro - 회사소개 뷰 반환")
    void companyIntro_returnsView() throws Exception {
        mockMvc.perform(get("/company/intro"))
                .andExpect(status().isOk())
                .andExpect(view().name("sub01_01"));
    }

    @Test
    @DisplayName("GET /business/intro - 사업소개 뷰 반환")
    void businessIntro_returnsView() throws Exception {
        mockMvc.perform(get("/business/intro"))
                .andExpect(status().isOk())
                .andExpect(view().name("sub02_01"));
    }

    @Test
    @DisplayName("GET /company/map - 오시는길 뷰 반환")
    void companyMap_returnsView() throws Exception {
        mockMvc.perform(get("/company/map"))
                .andExpect(status().isOk())
                .andExpect(view().name("sub01_05"));
    }

    @TestConfiguration
    static class MybatisTestConfig {
        @Bean
        public SqlSessionFactory sqlSessionFactory() throws Exception {
            TransactionFactory tf = new SpringManagedTransactionFactory();
            javax.sql.DataSource ds = Mockito.mock(javax.sql.DataSource.class);
            Environment env = new Environment("test", tf, ds);
            org.apache.ibatis.session.Configuration conf = new org.apache.ibatis.session.Configuration(env);
            SqlSessionFactory factory = Mockito.mock(SqlSessionFactory.class);
            Mockito.lenient().when(factory.getConfiguration()).thenReturn(conf);
            return factory;
        }
    }
}
