package com.infoepoch.pms.agent.platform.model.application;

import com.infoepoch.pms.agent.platform.model.domain.AiModelConfig;
import com.infoepoch.pms.agent.platform.model.domain.AiModelProvider;
import com.infoepoch.pms.agent.platform.model.domain.irepository.IAiModelConfigRepository;
import com.infoepoch.pms.agent.platform.model.domain.irepository.IAiModelProviderRepository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class ModelQueryServiceTest {

    @Mock
    private IAiModelConfigRepository modelConfigRepository;

    @Mock
    private IAiModelProviderRepository modelProviderRepository;

    @Test
    void shouldAttachProviderWhenFindingById() {
        when(modelConfigRepository.findById("config-1")).thenReturn(Optional.of(configWithoutProvider("config-1", "provider-1")));
        when(modelProviderRepository.findById("provider-1")).thenReturn(Optional.of(provider()));

        ModelQueryService service = new ModelQueryService(modelConfigRepository, modelProviderRepository);

        Optional<AiModelConfig> result = service.findById("config-1");

        assertTrue(result.isPresent());
        assertNotNull(result.orElseThrow().getProvider());
        assertEquals("provider-1", result.orElseThrow().getProvider().getId());
    }

    @Test
    void shouldReturnEmptyWhenModelConfigNotFound() {
        when(modelConfigRepository.findById("missing")).thenReturn(Optional.empty());

        ModelQueryService service = new ModelQueryService(modelConfigRepository, modelProviderRepository);

        Optional<AiModelConfig> result = service.findById("missing");

        assertTrue(result.isEmpty());
    }

    @Test
    void shouldKeepProviderNullWhenProviderIdIsNull() {
        when(modelConfigRepository.findById("config-2")).thenReturn(Optional.of(configWithoutProvider("config-2", null)));

        ModelQueryService service = new ModelQueryService(modelConfigRepository, modelProviderRepository);

        Optional<AiModelConfig> result = service.findById("config-2");

        assertTrue(result.isPresent());
        assertNull(result.orElseThrow().getProvider());
        verifyNoInteractions(modelProviderRepository);
    }

    private AiModelConfig configWithoutProvider(String id, String providerId) {
        return new AiModelConfig(
                id,
                providerId,
                "qwen-max",
                "LLM",
                "Qwen Max",
                8192,
                BigDecimal.ONE,
                32,
                null,
                Boolean.TRUE,
                Boolean.TRUE,
                null,
                true,
                null,
                null,
                LocalDateTime.now(),
                LocalDateTime.now()
        );
    }

    private AiModelProvider provider() {
        return AiModelProvider.restore(
                "provider-1",
                "DashScope",
                "DASHSCOPE",
                null,
                "sk-test",
                null,
                "provider",
                true,
                null,
                null,
                LocalDateTime.now(),
                LocalDateTime.now()
        );
    }
}
