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

import com.infoepoch.pms.agent.platform.agent.domain.irepository.IAgentRepository;
import com.infoepoch.pms.agent.platform.chatbot.domain.irepository.IChatbotRepository;
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 com.infoepoch.pms.agent.platform.model.domain.irepository.ISystemSettingsRepository;
import com.infoepoch.pms.agent.platform.shared.exception.BusinessException;
import com.infoepoch.pms.agent.platform.shared.response.ResultCode;
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.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class ModelProviderServiceTest {

    @Mock
    private IAiModelProviderRepository providerRepository;

    @Mock
    private IAiModelConfigRepository configRepository;

    @Mock
    private ISystemSettingsRepository systemSettingsRepository;

    @Mock
    private ModelProvisionService modelProvisionService;

    @Mock
    private IAgentRepository agentRepository;

    @Mock
    private IChatbotRepository chatbotRepository;

    @Mock
    private SystemSettingsService systemSettingsService;

    @Test
    void shouldRejectDeleteWhenProviderHasReferencedConfig() {
        LocalDateTime now = LocalDateTime.now();
        AiModelProvider provider = AiModelProvider.restore(
                "provider-1",
                "OpenAI",
                "OPENAI",
                null,
                null,
                null,
                null,
                true,
                null,
                null,
                now,
                now
        );
        AiModelConfig config = new AiModelConfig(
                "config-1",
                "provider-1",
                "gpt-4o",
                "LLM",
                "GPT-4o",
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                true,
                null,
                null,
                now,
                now
        );
        when(providerRepository.findById("provider-1")).thenReturn(Optional.of(provider));
        when(configRepository.findAllByProviderId("provider-1")).thenReturn(List.of(config));
        when(agentRepository.existsByModelConfigId("config-1")).thenReturn(true);
        ModelProviderService service = new ModelProviderService(
                providerRepository,
                configRepository,
                systemSettingsRepository,
                modelProvisionService,
                agentRepository,
                chatbotRepository,
                systemSettingsService
        );

        BusinessException ex = assertThrows(BusinessException.class, () -> service.delete("provider-1"));

        assertEquals(ResultCode.RESOURCE_IN_USE, ex.getResultCode());
        verify(configRepository, never()).delete(anyString());
        verify(providerRepository, never()).delete("provider-1");
    }

    @Test
    void shouldClearDefaultModelReferencesWhenDeletingProvider() {
        LocalDateTime now = LocalDateTime.now();
        AiModelProvider provider = AiModelProvider.restore(
                "provider-1",
                "OpenAI",
                "OPENAI",
                null,
                null,
                null,
                null,
                true,
                null,
                null,
                now,
                now
        );
        AiModelConfig llmConfig = new AiModelConfig(
                "config-llm",
                "provider-1",
                "gpt-4o",
                "LLM",
                "GPT-4o",
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                true,
                null,
                null,
                now,
                now
        );
        AiModelConfig embeddingConfig = new AiModelConfig(
                "config-embedding",
                "provider-1",
                "text-embedding-v3",
                "EMBEDDING",
                "Embedding",
                null,
                null,
                null,
                1024,
                null,
                null,
                null,
                true,
                null,
                null,
                now,
                now
        );
        when(providerRepository.findById("provider-1")).thenReturn(Optional.of(provider));
        when(configRepository.findAllByProviderId("provider-1")).thenReturn(List.of(llmConfig, embeddingConfig));
        when(agentRepository.existsByModelConfigId("config-llm")).thenReturn(false);
        when(agentRepository.existsByModelConfigId("config-embedding")).thenReturn(false);
        when(chatbotRepository.existsByModelConfigId("config-llm")).thenReturn(false);
        when(chatbotRepository.existsByModelConfigId("config-embedding")).thenReturn(false);
        ModelProviderService service = new ModelProviderService(
                providerRepository,
                configRepository,
                systemSettingsRepository,
                modelProvisionService,
                agentRepository,
                chatbotRepository,
                systemSettingsService
        );

        service.delete("provider-1");

        verify(systemSettingsService).clearDefaultModelReferences(List.of("config-llm", "config-embedding"));
        verify(configRepository).delete("config-llm");
        verify(configRepository).delete("config-embedding");
        verify(providerRepository).delete("provider-1");
    }
}
