package org.raddatz.familienarchiv.dashboard;

import org.junit.jupiter.api.Test;
import org.raddatz.familienarchiv.security.SecurityConfig;
import org.raddatz.familienarchiv.dashboard.StatsDTO;
import org.raddatz.familienarchiv.security.PermissionAspect;
import org.raddatz.familienarchiv.user.CustomUserDetailsService;
import org.raddatz.familienarchiv.dashboard.StatsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration;
import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
import org.springframework.context.annotation.Import;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;

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.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(StatsController.class)
@Import({SecurityConfig.class, PermissionAspect.class, AopAutoConfiguration.class})
class StatsControllerTest {

    @Autowired MockMvc mockMvc;

    @MockitoBean StatsService statsService;
    @MockitoBean CustomUserDetailsService customUserDetailsService;

    @Test
    void getStats_returns401_whenUnauthenticated() throws Exception {
        mockMvc.perform(get("/api/stats"))
                .andExpect(status().isUnauthorized());
    }

    @Test
    @WithMockUser
    void getStats_returns403_whenUserLacksReadAll() throws Exception {
        mockMvc.perform(get("/api/stats"))
                .andExpect(status().isForbidden());
    }

    @Test
    @WithMockUser(authorities = "READ_ALL")
    void getStats_returns200_withCorrectCounts() throws Exception {
        when(statsService.getStats()).thenReturn(new StatsDTO(4L, 12L, 2L));

        mockMvc.perform(get("/api/stats"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.totalPersons").value(4))
                .andExpect(jsonPath("$.totalDocuments").value(12));
    }

    @Test
    @WithMockUser(authorities = "READ_ALL")
    void getStats_returns200_withZeroCounts() throws Exception {
        when(statsService.getStats()).thenReturn(new StatsDTO(0L, 0L, 0L));

        mockMvc.perform(get("/api/stats"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.totalPersons").value(0))
                .andExpect(jsonPath("$.totalDocuments").value(0));
    }
}
