package placement

import (
	"fmt"
	"strings"

	"haixun-backend/internal/library/websearch"
)

// ConnectionPrefsInput mirrors persisted account connection prefs without importing threads_account.
type ConnectionPrefsInput struct {
	DevMode          bool
	SearchSourceMode string
}

// MemberContext is resolved per login member (email account) + active Threads operating account.
type MemberContext struct {
	TenantID              string
	OwnerUID              string
	ActiveAccountID       string
	DevMode               bool
	SearchSourceMode      SearchSourceMode
	AllowsThreadsAPI      bool
	AllowsBrave           bool
	AllowsCrawler         bool
	WebSearchProvider     string
	BraveAPIKey           string
	ExaAPIKey             string
	BraveCountry          string
	BraveSearchLang       string
	ExaUserLocation       string
	ApiConnected          bool
	BrowserConnected      bool
	ThreadsAPIAccessToken string
	ScrapeReplies         bool
	RepliesPerPost        int
}

type ResearchSettings struct {
	WebSearchProvider string
	BraveAPIKey       string
	ExaAPIKey         string
	BraveCountry      string
	BraveSearchLang   string
	ExaUserLocation   string
	ExpandStrategy    string
}

func BuildMemberContext(
	tenantID, ownerUID, activeAccountID string,
	prefs ConnectionPrefsInput,
	apiConnected, browserConnected bool,
	research ResearchSettings,
	scrapeReplies bool,
	repliesPerPost int,
) MemberContext {
	mode := ParseSearchSourceMode(prefs.SearchSourceMode)
	if prefs.DevMode && strings.TrimSpace(prefs.SearchSourceMode) == "" {
		mode = SearchSourceCrawler
	}
	allowsCrawler := ModeAllowsCrawler(mode)
	allowsThreads := ModeAllowsThreadsAPI(mode)
	allowsBrave := ModeAllowsBrave(mode)

	country := strings.TrimSpace(research.BraveCountry)
	if country == "" {
		country = "tw"
	}
	lang := strings.TrimSpace(research.BraveSearchLang)
	if lang == "" {
		lang = "zh-hant"
	}
	userLocation := strings.TrimSpace(research.ExaUserLocation)
	if userLocation == "" {
		userLocation = "TW"
	}

	if repliesPerPost <= 0 {
		repliesPerPost = 10
	}

	return MemberContext{
		TenantID:          tenantID,
		OwnerUID:          ownerUID,
		ActiveAccountID:   activeAccountID,
		DevMode:           prefs.DevMode,
		SearchSourceMode:  mode,
		AllowsThreadsAPI:  allowsThreads,
		AllowsBrave:       allowsBrave,
		AllowsCrawler:     allowsCrawler,
		WebSearchProvider: string(websearch.ParseProvider(research.WebSearchProvider)),
		BraveAPIKey:       strings.TrimSpace(research.BraveAPIKey),
		ExaAPIKey:         strings.TrimSpace(research.ExaAPIKey),
		BraveCountry:      country,
		BraveSearchLang:   lang,
		ExaUserLocation:   userLocation,
		ApiConnected:      apiConnected,
		BrowserConnected:  browserConnected,
		ScrapeReplies:     scrapeReplies,
		RepliesPerPost:    repliesPerPost,
	}
}

func (c MemberContext) PayloadFields() map[string]any {
	return map[string]any{
		"tenant_id":           c.TenantID,
		"owner_uid":           c.OwnerUID,
		"threads_account_id":  c.ActiveAccountID,
		"dev_mode":            c.DevMode,
		"search_source_mode":  string(c.SearchSourceMode),
		"allows_threads_api":  c.AllowsThreadsAPI,
		"allows_brave":        c.AllowsBrave,
		"allows_crawler":      c.AllowsCrawler,
		"web_search_provider": c.WebSearchProvider,
		"brave_country":       c.BraveCountry,
		"brave_search_lang":   c.BraveSearchLang,
		"exa_user_location":   c.ExaUserLocation,
		"api_connected":       c.ApiConnected,
		"browser_connected":   c.BrowserConnected,
		"scrape_replies":      c.ScrapeReplies,
		"replies_per_post":    c.RepliesPerPost,
	}
}

func (c MemberContext) WebSearchProviderEnum() websearch.Provider {
	return websearch.ParseProvider(c.WebSearchProvider)
}

func (c MemberContext) WebSearchAPIKey() string {
	if c.WebSearchProviderEnum() == websearch.ProviderExa {
		return strings.TrimSpace(c.ExaAPIKey)
	}
	return strings.TrimSpace(c.BraveAPIKey)
}

func (c MemberContext) WebSearchConfig() websearch.Config {
	return websearch.ConfigFromMember(
		c.BraveAPIKey,
		c.ExaAPIKey,
		c.WebSearchProvider,
		c.BraveCountry,
		c.BraveSearchLang,
		c.ExaUserLocation,
	)
}

func (c MemberContext) WebSearchProviderLabel() string {
	return websearch.ProviderLabel(c.WebSearchProviderEnum())
}

func (c MemberContext) WebSearchDiscoverChannel() DiscoverChannel {
	if c.WebSearchProviderEnum() == websearch.ProviderExa {
		return DiscoverExa
	}
	return DiscoverBrave
}

func MissingWebSearchKey(research ResearchSettings) bool {
	return strings.TrimSpace(websearch.ActiveAPIKey(websearch.ConfigFromMember(
		research.BraveAPIKey,
		research.ExaAPIKey,
		research.WebSearchProvider,
		research.BraveCountry,
		research.BraveSearchLang,
		research.ExaUserLocation,
	))) == ""
}

func WebSearchKeyRequiredMessage(research ResearchSettings) string {
	provider := websearch.ParseProvider(research.WebSearchProvider)
	return fmt.Sprintf("請在設定頁設定 %s Search API key（跟隨此登入帳號）", websearch.ProviderLabel(provider))
}
