package com.saas.voip.service.provider.vapi;

import com.saas.shared.exception.BusinessException;
import com.saas.shared.exception.ErrorCode;
import com.saas.voip.dto.request.CreateVapiAssistantRequest;
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.util.ReflectionTestUtils;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;

import static org.junit.jupiter.api.Assertions.*;

/**
 * Unit Tests for VapiService
 */
@ExtendWith(MockitoExtension.class)
@DisplayName("VapiService Unit Tests")
class VapiServiceTest {

    @Mock
    private RestTemplate restTemplate;

    @InjectMocks
    private VapiService vapiService;

    private CreateVapiAssistantRequest testRequest;

    @BeforeEach
    void setUp() {
        testRequest = CreateVapiAssistantRequest.builder()
            .name("Medical Assistant")
            .description("AI assistant for patient calls")
            .systemPrompt("You are a helpful medical receptionist")
            .firstMessage("Hello, how can I help you today?")
            .voiceProvider("11labs")
            .voiceId("voice_123")
            .model("gpt-4")
            .temperature(0.7)
            .maxDurationSeconds(1800)
            .enableTranscription(true)
            .enableRecording(true)
            .build();

        // Set API key via reflection
        ReflectionTestUtils.setField(vapiService, "vapiApiKey", "test-api-key");
        ReflectionTestUtils.setField(vapiService, "vapiBaseUrl", "https://api.vapi.ai");
    }

    @Test
    @DisplayName("Should throw exception when Vapi API key not configured")
    void testCreateAssistantNoApiKey() {
        // Arrange
        ReflectionTestUtils.setField(vapiService, "vapiApiKey", "");

        // Act & Assert
        BusinessException exception = assertThrows(BusinessException.class,
            () -> vapiService.createAssistant(testRequest));
        
        assertEquals(ErrorCode.INVALID_INPUT, exception.getErrorCode());
        assertTrue(exception.getMessage().contains("Vapi API key is not configured"));
    }

    @Test
    @DisplayName("Should validate API key presence for fetchAssistantsFromApi")
    void testFetchAssistantsNoApiKey() {
        // Arrange
        ReflectionTestUtils.setField(vapiService, "vapiApiKey", null);

        // Act & Assert
        BusinessException exception = assertThrows(BusinessException.class,
            () -> vapiService.fetchAssistantsFromApi());
        
        assertEquals(ErrorCode.INVALID_INPUT, exception.getErrorCode());
    }

    @Test
    @DisplayName("Should validate API key presence for getAssistant")
    void testGetAssistantNoApiKey() {
        // Arrange
        ReflectionTestUtils.setField(vapiService, "vapiApiKey", "");

        // Act & Assert
        BusinessException exception = assertThrows(BusinessException.class,
            () -> vapiService.getAssistant("assistant_123"));
        
        assertEquals(ErrorCode.INVALID_INPUT, exception.getErrorCode());
    }

    @Test
    @DisplayName("Should validate API key presence for updateAssistant")
    void testUpdateAssistantNoApiKey() {
        // Arrange
        ReflectionTestUtils.setField(vapiService, "vapiApiKey", "");

        // Act & Assert
        BusinessException exception = assertThrows(BusinessException.class,
            () -> vapiService.updateAssistant("assistant_123", testRequest));
        
        assertEquals(ErrorCode.INVALID_INPUT, exception.getErrorCode());
    }

    @Test
    @DisplayName("Should validate API key presence for deleteAssistant")
    void testDeleteAssistantNoApiKey() {
        // Arrange
        ReflectionTestUtils.setField(vapiService, "vapiApiKey", null);

        // Act & Assert
        BusinessException exception = assertThrows(BusinessException.class,
            () -> vapiService.deleteAssistant("assistant_123"));
        
        assertEquals(ErrorCode.INVALID_INPUT, exception.getErrorCode());
    }

    @Test
    @DisplayName("Should have correct base URL configuration")
    void testBaseUrlConfiguration() {
        String baseUrl = (String) ReflectionTestUtils.getField(vapiService, "vapiBaseUrl");
        assertEquals("https://api.vapi.ai", baseUrl);
    }
}
