package placement

import (
	"context"
	"fmt"
)

// ShouldTryCrawlerFirst reports whether discover should attempt Playwright before Threads API
// to minimize official API calls when a browser session is available.
func ShouldTryCrawlerFirst(m MemberContext) bool {
	if !m.AllowsCrawler || !m.BrowserConnected || m.CrawlerBlocked() {
		return false
	}
	switch m.SearchSourceMode {
	case SearchSourceCrawler, SearchSourceThreadsCrawler, SearchSourceBraveCrawler:
		return true
	case SearchSourceMixed, SearchSourceThreadsBrave:
		return true
	default:
		return false
	}
}

// CrawlerBlocked returns true when the mode is API-only or web-search-only.
func (m MemberContext) CrawlerBlocked() bool {
	switch m.SearchSourceMode {
	case SearchSourceThreads, SearchSourceBrave:
		return true
	default:
		return false
	}
}

// CrawlerFallbackAllowed returns true when crawler may be used after API/web search fails.
func (m MemberContext) CrawlerFallbackAllowed() bool {
	if !m.AllowsCrawler || !m.BrowserConnected {
		return false
	}
	switch m.SearchSourceMode {
	case SearchSourceThreadsCrawler, SearchSourceBraveCrawler, SearchSourceMixed:
		return true
	default:
		return false
	}
}

// HasDiscoverPath reports whether at least one discover backend is configured and connected.
func (m MemberContext) HasDiscoverPath() bool {
	if m.AllowsCrawler && m.BrowserConnected {
		return true
	}
	if m.AllowsThreadsAPI && m.ApiConnected {
		return true
	}
	if m.AllowsBrave && m.WebSearchAPIKey() != "" {
		return true
	}
	return false
}

// DiscoverPathLabel summarizes the active routing for job progress UI.
func (m MemberContext) DiscoverPathLabel() string {
	if ShouldTryCrawlerFirst(m) {
		if m.AllowsThreadsAPI && m.ApiConnected {
			return "爬蟲優先（不足再 API）"
		}
		return "爬蟲"
	}
	if m.SearchSourceMode == SearchSourceCrawler {
		return "爬蟲"
	}
	if m.AllowsThreadsAPI && m.ApiConnected {
		return "Threads API"
	}
	if m.AllowsBrave {
		return m.WebSearchProviderLabel()
	}
	return string(m.SearchSourceMode)
}

func discoverMissingPathError(m MemberContext) error {
	switch m.SearchSourceMode {
	case SearchSourceCrawler:
		return fmt.Errorf("請先同步 Chrome Session 以使用爬蟲搜尋")
	case SearchSourceThreadsCrawler, SearchSourceBraveCrawler:
		if !m.BrowserConnected && !m.ApiConnected && m.WebSearchAPIKey() == "" {
			return fmt.Errorf("請同步 Chrome Session 或完成 Threads API / Web Search 連線")
		}
		if !m.BrowserConnected {
			return fmt.Errorf("爬蟲優先模式建議先同步 Chrome Session；亦可改用僅 Threads API")
		}
		return fmt.Errorf("請完成 Threads API 或 Web Search 連線作為備援")
	case SearchSourceThreads, SearchSourceThreadsBrave:
		return fmt.Errorf("請先完成 Threads API 連線")
	case SearchSourceBrave:
		return fmt.Errorf("請在設定頁設定 %s Search API key", m.WebSearchProviderLabel())
	case SearchSourceMixed:
		return fmt.Errorf("請同步 Chrome Session、完成 Threads API 或設定 Web Search API key 至少一項")
	default:
		return fmt.Errorf("目前搜尋來源模式無可用管道：%s", m.SearchSourceMode)
	}
}

func runCrawlerDiscover(ctx context.Context, req DiscoverRequest) ([]DiscoverPost, error) {
	if req.Crawler == nil {
		return nil, fmt.Errorf("crawler search not configured")
	}
	keyword := CrawlerKeywordFromQuery(req.Query, req.Keyword)
	if keyword == "" {
		return nil, fmt.Errorf("crawler keyword is empty")
	}
	return req.Crawler(ctx, req.Member, keyword, req.Limit)
}
