package service

import (
	"strings"

	"nex/backend/internal/domain"
	"nex/backend/internal/repository"
	"nex/backend/pkg/modelid"

	appErrors "nex/backend/pkg/errors"
)

type providerService struct {
	providerRepo repository.ProviderRepository
	modelRepo    repository.ModelRepository
	cache        *RoutingCache
}

func NewProviderService(providerRepo repository.ProviderRepository, modelRepo repository.ModelRepository, cache *RoutingCache) ProviderService {
	return &providerService{providerRepo: providerRepo, modelRepo: modelRepo, cache: cache}
}

func (s *providerService) Create(provider *domain.Provider) error {
	if err := modelid.ValidateProviderID(provider.ID); err != nil {
		return appErrors.ErrInvalidProviderID
	}
	provider.Enabled = true
	err := s.providerRepo.Create(provider)
	if err != nil {
		if isUniqueConstraintError(err) {
			return appErrors.ErrConflict
		}
		return err
	}
	s.cache.SetProvider(provider)
	return nil
}

func (s *providerService) Get(id string) (*domain.Provider, error) {
	return s.providerRepo.GetByID(id)
}

func (s *providerService) List() ([]domain.Provider, error) {
	return s.providerRepo.List()
}

func (s *providerService) Update(id string, updates map[string]interface{}) error {
	if _, ok := updates["id"]; ok {
		return appErrors.ErrImmutableField
	}
	err := s.providerRepo.Update(id, updates)
	if err != nil {
		return err
	}
	s.cache.InvalidateProvider(id)
	return nil
}

func (s *providerService) Delete(id string) error {
	err := s.providerRepo.Delete(id)
	if err != nil {
		return err
	}
	s.cache.InvalidateProvider(id)
	return nil
}

// ListEnabledModels 返回所有启用的模型（用于 Models 接口本地聚合）
func (s *providerService) ListEnabledModels() ([]domain.Model, error) {
	return s.modelRepo.ListEnabled()
}

// GetModelByProviderAndName 按 provider_id 和 model_name 查询模型（用于 ModelInfo 接口本地查询）
func (s *providerService) GetModelByProviderAndName(providerID, modelName string) (*domain.Model, error) {
	return s.modelRepo.FindByProviderAndModelName(providerID, modelName)
}

// isUniqueConstraintError 判断是否为数据库唯一约束冲突错误
func isUniqueConstraintError(err error) bool {
	if err == nil {
		return false
	}
	msg := strings.ToLower(err.Error())
	return strings.Contains(msg, "unique constraint") || strings.Contains(msg, "duplicate")
}
