package com.zhengmeng.ocrplatform.llm;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Service
public class LlmModelService {
    private final LlmModelRepository repository;

    public LlmModelService(LlmModelRepository repository) {
        this.repository = repository;
    }

    @Transactional(readOnly = true)
    public List<LlmModelItem> listModels() {
        return repository.findAllByOrderByProviderAscDisplayNameAsc().stream()
                .map(LlmModelItem::fromEntity)
                .toList();
    }

    @Transactional
    public LlmModelItem updateModel(String modelId, LlmModelUpdateRequest request) {
        LlmModelEntity entity = repository.findByModelId(modelId)
                .orElseThrow(() -> new LlmModelNotFoundException(modelId));
        apply(entity, request);
        if (Boolean.TRUE.equals(request.selected())) {
            clearOtherSelectedModels(modelId);
            entity.setSelected(true);
            entity.setEnabled(true);
        }
        entity.setUpdatedAt(LocalDateTime.now());
        return LlmModelItem.fromEntity(repository.save(entity));
    }

    @Transactional
    public LlmModelItem selectModel(String modelId) {
        LlmModelEntity entity = repository.findByModelId(modelId)
                .orElseThrow(() -> new LlmModelNotFoundException(modelId));
        clearOtherSelectedModels(modelId);
        entity.setSelected(true);
        entity.setEnabled(true);
        entity.setUpdatedAt(LocalDateTime.now());
        return LlmModelItem.fromEntity(repository.save(entity));
    }

    @Transactional(readOnly = true)
    public Optional<LlmChatBotConfig> currentChatBotConfig() {
        return repository.findFirstBySelectedTrueAndEnabledTrueOrderByIdAsc()
                .filter(entity -> entity.getApiKey() != null && !entity.getApiKey().isBlank())
                .map(entity -> new LlmChatBotConfig(
                        entity.getModelId(),
                        entity.getModelName(),
                        entity.getBaseUrl(),
                        entity.getApiType(),
                        entity.getApiKey(),
                        Boolean.TRUE.equals(entity.getThinkingEnabled())
                ));
    }

    private void apply(LlmModelEntity entity, LlmModelUpdateRequest request) {
        if (request.displayName() != null && !request.displayName().isBlank()) {
            entity.setDisplayName(request.displayName().trim());
        }
        if (request.baseUrl() != null && !request.baseUrl().isBlank()) {
            entity.setBaseUrl(request.baseUrl().trim());
        }
        if (request.modelName() != null && !request.modelName().isBlank()) {
            entity.setModelName(request.modelName().trim());
        }
        if (request.apiType() != null && !request.apiType().isBlank()) {
            entity.setApiType(request.apiType().trim());
        }
        if (request.apiKey() != null) {
            entity.setApiKey(request.apiKey().isBlank() ? null : request.apiKey().trim());
        }
        if (request.enabled() != null) {
            entity.setEnabled(request.enabled());
        }
        if (request.selected() != null) {
            entity.setSelected(request.selected());
        }
        if (request.thinkingEnabled() != null) {
            entity.setThinkingEnabled(request.thinkingEnabled());
        }
    }

    private void clearOtherSelectedModels(String selectedModelId) {
        repository.findAll().forEach(entity -> {
            if (!entity.getModelId().equals(selectedModelId) && Boolean.TRUE.equals(entity.getSelected())) {
                entity.setSelected(false);
                entity.setUpdatedAt(LocalDateTime.now());
                repository.save(entity);
            }
        });
    }
}
