package placement

import (
	"context"
	"fmt"
)

// DiscoverChannel identifies which backend fulfilled a placement discover query.
type DiscoverChannel string

const (
	DiscoverThreadsAPI DiscoverChannel = "threads_api"
	DiscoverBrave      DiscoverChannel = "brave"
	DiscoverCrawler    DiscoverChannel = "crawler"
)

// DiscoverRequest is used by scan jobs; expand-graph only uses Brave knowledge_expand.
type DiscoverRequest struct {
	Query   string
	Keyword string // plain tag for crawler; optional
	Recency bool
	Limit   int
	Member  MemberContext
	Crawler CrawlerSearchFn
}

type DiscoverPost struct {
	Text       string
	Permalink  string
	ExternalID string
	Author     string
	PostedAt   string
	LikeCount  int
	ReplyCount int
	Source     DiscoverChannel
}

// Discover runs keyword discovery respecting the member's connection prefs.
// Formal mode (dev_mode=false) never falls back to crawler.
func Discover(ctx context.Context, req DiscoverRequest) ([]DiscoverPost, DiscoverChannel, error) {
	m := req.Member
	if m.DevMode {
		if !m.BrowserConnected {
			return nil, "", fmt.Errorf("開發模式需先同步 Chrome Session")
		}
		if req.Crawler == nil {
			return nil, DiscoverCrawler, fmt.Errorf("crawler search not configured")
		}
		keyword := CrawlerKeywordFromQuery(req.Query, req.Keyword)
		if keyword == "" {
			return nil, DiscoverCrawler, fmt.Errorf("crawler keyword is empty")
		}
		posts, err := req.Crawler(ctx, m, keyword, req.Limit)
		if err != nil {
			return nil, DiscoverCrawler, err
		}
		return posts, DiscoverCrawler, nil
	}

	if m.AllowsThreadsAPI {
		if !m.ApiConnected {
			return nil, "", fmt.Errorf("正式模式需先完成 Threads API 連線")
		}
		posts, err := keywordSearchViaThreadsAPI(ctx, req)
		if err == nil && len(posts) > 0 {
			return posts, DiscoverThreadsAPI, nil
		}
		if err != nil && !m.AllowsBrave {
			return nil, "", err
		}
	}

	if m.AllowsBrave {
		if m.BraveAPIKey == "" {
			return nil, "", fmt.Errorf("請在設定頁設定 Brave Search API key（跟隨此登入帳號）")
		}
		return nil, DiscoverBrave, fmt.Errorf("brave threads discover delegated to worker")
	}

	return nil, "", fmt.Errorf("目前搜尋來源模式無可用管道：%s", m.SearchSourceMode)
}
