package settings

import (
	"context"

	"apps/backend/internal/middleware"
	"apps/backend/internal/module/ai"
	"apps/backend/internal/module/member/domain"
	"apps/backend/internal/svc"
	"apps/backend/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type SaveAiLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewSaveAiLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SaveAiLogic {
	return &SaveAiLogic{Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx}
}

func (l *SaveAiLogic) SaveAi(req *types.SaveAiReq) (*types.AiSettingsData, error) {
	uid, _ := middleware.UIDFrom(l.ctx)
	st, err := l.svcCtx.Members.GetSettings(l.ctx, uid)
	if err != nil {
		return nil, err
	}
	if st == nil {
		st = domain.DefaultSettings(uid)
	}
	if st.ProviderAPIKeys == nil {
		st.ProviderAPIKeys = map[string]string{}
	}
	// migrate legacy single key into map
	if st.APIKey != "" && st.Provider != "" && st.ProviderAPIKeys[st.Provider] == "" {
		st.ProviderAPIKeys[st.Provider] = st.APIKey
	}

	provider := st.Provider
	if req.Provider != "" {
		provider = req.Provider
	} else if req.ResearchProvider != "" {
		provider = req.ResearchProvider
	}
	provider = ai.NormalizeProvider(provider)
	st.Provider = provider

	if req.Model != "" {
		st.Model = req.Model
	} else if req.ResearchModel != "" {
		st.Model = req.ResearchModel
	}

	// BYOK for this provider
	if req.ApiKey != "" {
		st.SetKeyForProvider(provider, req.ApiKey)
	}
	if req.ResearchApiKey != "" {
		st.SetKeyForProvider(provider, req.ResearchApiKey)
	}
	if req.ApiKeyConfigured != nil && !*req.ApiKeyConfigured {
		st.SetKeyForProvider(provider, "")
	}

	// validate model against live list (or fallback)
	list, _, _ := loadModelsForProvider(l.ctx, l.svcCtx, st, provider)
	st.Model = pickModel(st.Model, list)

	st.APIKeyConfigured = st.HasKeyForProvider(provider)
	st.ResearchAPIKeyConfigured = st.APIKeyConfigured
	st.UpdatedAt = domain.NowNano()

	if err := l.svcCtx.Members.SaveSettings(l.ctx, uid, st); err != nil {
		return nil, err
	}
	// return combined settings + models
	return NewGetAiLogic(l.ctx, l.svcCtx).GetAi(&types.GetAiReq{Provider: provider})
}
