package mx.gob.slp.baseadminweb.jar;

import com.jayway.jsonpath.JsonPath;
import mx.gob.slp.baseadminweb.application.service.PassCodeService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.MediaType;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("test")
class PassCodeApiTests {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private PassCodeService passCodeService;

    private String accessToken;

    @BeforeEach
    void loginScanner() throws Exception {
        MvcResult loginResult = mockMvc.perform(post("/api/auth/login")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content("{\"username\":\"scanner\",\"password\":\"Scanner123*\"}"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.success").value(true))
                .andReturn();

        accessToken = JsonPath.read(loginResult.getResponse().getContentAsString(), "$.accessToken");
    }

    @Test
    void shouldScanCreatedPassCode() throws Exception {
        var created = passCodeService.create("Pase prueba");

        mockMvc.perform(post("/api/pass-codes/scan")
                        .header("Authorization", "Bearer " + accessToken)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content("{\"code\":\"" + created.getCode() + "\"}"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.success").value(true))
                .andExpect(jsonPath("$.passCode.scanned").value(true))
                .andExpect(jsonPath("$.passCode.status").value("UTILIZADO"));

        mockMvc.perform(post("/api/pass-codes/scan")
                        .header("Authorization", "Bearer " + accessToken)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content("{\"code\":\"" + created.getCode() + "\"}"))
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("$.success").value(false));
    }

    @Test
    void shouldRejectUnknownPassCode() throws Exception {
        mockMvc.perform(post("/api/pass-codes/scan")
                        .header("Authorization", "Bearer " + accessToken)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content("{\"code\":\"ZZZZZZZZZZ\"}"))
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("$.success").value(false));
    }

    @Test
    void shouldRejectScanWithoutToken() throws Exception {
        mockMvc.perform(post("/api/pass-codes/scan")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content("{\"code\":\"ZZZZZZZZZZ\"}"))
                .andExpect(status().isUnauthorized());
    }

    @Test
    void shouldRejectAdminLoginOnApi() throws Exception {
        mockMvc.perform(post("/api/auth/login")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content("{\"username\":\"admin\",\"password\":\"Admin123*\"}"))
                .andExpect(status().isUnauthorized())
                .andExpect(jsonPath("$.success").value(false));
    }
}