package ai

import (
	"context"
	"fmt"
	"strings"
)

// Client is AI provider transport (real HTTP or fake).
type Client interface {
	Complete(ctx context.Context, apiKey, model, prompt string) (string, error)
	// CompleteStream 串流 delta；onDelta 可為 nil。回傳完整正文。
	CompleteStream(ctx context.Context, apiKey, model, prompt string, onDelta func(chunk string) error) (string, error)
	ListModels(ctx context.Context, apiKey string) ([]string, error)
}

// FakeClient for tests / when no real key path needed.
type FakeClient struct {
	Fail   bool
	Models []string
}

func (f *FakeClient) Complete(ctx context.Context, apiKey, model, prompt string) (string, error) {
	if f.Fail || apiKey == "" {
		return "", fmt.Errorf("ai call failed: no key or forced fail")
	}
	_ = SystemPromptForLanguage(ResponseLanguageFrom(ctx)) // ensure always defined for real clients
	if len(prompt) > 200 {
		prompt = prompt[:200]
	}
	return fmt.Sprintf("[%s] %s", model, strings.TrimSpace(prompt)), nil
}

func (f *FakeClient) ListModels(_ context.Context, apiKey string) ([]string, error) {
	if f.Fail || apiKey == "" {
		return nil, fmt.Errorf("list models failed: no key or forced fail")
	}
	if len(f.Models) > 0 {
		return append([]string(nil), f.Models...), nil
	}
	return []string{"grok-3", "grok-2", "grok-beta"}, nil
}

// ModelsForProvider — static catalog (fallback when live list fails).
func ModelsForProvider(provider string) []string {
	return FallbackModels(provider)
}
