package usecase

import (
	"context"
	"strings"

	"apps/backend/internal/module/ai"
	memberDomain "apps/backend/internal/module/member/domain"
	"apps/backend/internal/module/usage/domain"
)

// SettingsResolver uses member settings + platform config.
type SettingsResolver struct {
	Members          memberDomain.Repository
	PlatformAI       string // legacy / xAI fallback
	PlatformXAI      string
	PlatformOpenCode string
	PlatformExa      string
}

func (r *SettingsResolver) platformAIKey(provider string) string {
	switch ai.NormalizeProvider(provider) {
	case ai.ProviderOpenCodeGo:
		if k := strings.TrimSpace(r.PlatformOpenCode); k != "" {
			return k
		}
	default:
		if k := strings.TrimSpace(r.PlatformXAI); k != "" {
			return k
		}
		if k := strings.TrimSpace(r.PlatformAI); k != "" {
			return k
		}
	}
	return ""
}

func (r *SettingsResolver) Resolve(ctx context.Context, uid int64, meter string) (string, bool, error) {
	st, err := r.Members.GetSettings(ctx, uid)
	if err != nil {
		return "", false, err
	}
	if st == nil {
		st = memberDomain.DefaultSettings(uid)
	}
	mode, has := r.resolveSettings(st, meter)
	return mode, has, nil
}

func (r *SettingsResolver) resolveSettings(st *memberDomain.UserSettings, meter string) (string, bool) {
	provider := ai.NormalizeProvider(st.Provider)
	switch meter {
	case domain.MeterAICopy, domain.MeterAIResearch, domain.MeterAIImage:
		if st.KeyForProvider(provider) != "" {
			return domain.KeyModeByok, true
		}
		if r.platformAIKey(provider) != "" {
			return domain.KeyModePlatform, true
		}
		return "", false
	case domain.MeterWebSearch:
		if st.ExaAPIKeyConfigured && st.ExaAPIKey != "" {
			return domain.KeyModeByok, true
		}
		if r.PlatformExa != "" {
			return domain.KeyModePlatform, true
		}
		return "", false
	default:
		return "", false
	}
}

// ResolveKey returns actual key material for call (never log).
func (r *SettingsResolver) ResolveKey(ctx context.Context, uid int64, meter string) (keyMode, apiKey string, err error) {
	st, err := r.Members.GetSettings(ctx, uid)
	if err != nil {
		return "", "", err
	}
	if st == nil {
		st = memberDomain.DefaultSettings(uid)
	}
	mode, has := r.resolveSettings(st, meter)
	if !has {
		return "", "", domain.ErrNoKey
	}
	provider := ai.NormalizeProvider(st.Provider)
	switch mode {
	case domain.KeyModeByok:
		if meter == domain.MeterWebSearch {
			return mode, st.ExaAPIKey, nil
		}
		return mode, st.KeyForProvider(provider), nil
	default:
		if meter == domain.MeterWebSearch {
			return mode, r.PlatformExa, nil
		}
		return mode, r.platformAIKey(provider), nil
	}
}

var _ KeyResolver = (*SettingsResolver)(nil)
