package rest

import (
	"bufio"
	"os"
	"path/filepath"
	"strings"
)

func loadAIDocSnippets(query string) ([]AIDocSnippet, string, string) {
	root := findAIWorkspaceRoot()
	if root == "" {
		return nil, "", "workspace docs root unavailable for ai doc retrieval"
	}

	relativePaths := []string{
		"docs/11-references/ADDRESS_MATRIX_AND_STATUS.md",
		"docs/11-references/LIQUIDITY_POOLS_MASTER_MAP.md",
		"docs/11-references/DEPLOYED_TOKENS_BRIDGES_LPS_AND_ROUTING_STATUS.md",
		"docs/11-references/EXPLORER_TOKEN_LIST_CROSSCHECK.md",
		"explorer-monorepo/docs/EXPLORER_API_ACCESS.md",
	}

	terms := buildDocSearchTerms(query)
	if len(terms) == 0 {
		terms = []string{"chain 138", "bridge", "liquidity"}
	}

	snippets := []AIDocSnippet{}
	for _, rel := range relativePaths {
		fullPath := filepath.Join(root, rel)
		fileSnippets := scanDocForTerms(fullPath, rel, terms)
		snippets = append(snippets, fileSnippets...)
		if len(snippets) >= maxExplorerAIDocSnippets {
			break
		}
	}
	if len(snippets) == 0 {
		return nil, root, "no matching workspace docs found for ai context"
	}
	if len(snippets) > maxExplorerAIDocSnippets {
		snippets = snippets[:maxExplorerAIDocSnippets]
	}
	return snippets, root, ""
}

func findAIWorkspaceRoot() string {
	candidates := []string{}
	if envRoot := strings.TrimSpace(os.Getenv("EXPLORER_AI_WORKSPACE_ROOT")); envRoot != "" {
		candidates = append(candidates, envRoot)
	}
	if cwd, err := os.Getwd(); err == nil {
		candidates = append(candidates, cwd)
		dir := cwd
		for i := 0; i < 4; i++ {
			dir = filepath.Dir(dir)
			candidates = append(candidates, dir)
		}
	}
	candidates = append(candidates, "/opt/explorer-monorepo", "/home/intlc/projects/proxmox")

	for _, candidate := range candidates {
		if candidate == "" {
			continue
		}
		if fileExists(filepath.Join(candidate, "docs")) && (fileExists(filepath.Join(candidate, "explorer-monorepo")) || fileExists(filepath.Join(candidate, "smom-dbis-138")) || fileExists(filepath.Join(candidate, "config"))) {
			return candidate
		}
	}
	return ""
}

func scanDocForTerms(fullPath, relativePath string, terms []string) []AIDocSnippet {
	file, err := os.Open(fullPath)
	if err != nil {
		return nil
	}
	defer file.Close()

	normalizedTerms := make([]string, 0, len(terms))
	for _, term := range terms {
		term = strings.ToLower(strings.TrimSpace(term))
		if len(term) >= 3 {
			normalizedTerms = append(normalizedTerms, term)
		}
	}

	scanner := bufio.NewScanner(file)
	lineNumber := 0
	snippets := []AIDocSnippet{}
	for scanner.Scan() {
		lineNumber++
		line := scanner.Text()
		lower := strings.ToLower(line)
		for _, term := range normalizedTerms {
			if strings.Contains(lower, term) {
				snippets = append(snippets, AIDocSnippet{
					Path:    relativePath,
					Line:    lineNumber,
					Snippet: clipString(strings.TrimSpace(line), 280),
				})
				break
			}
		}
		if len(snippets) >= 2 {
			break
		}
	}
	return snippets
}

func buildDocSearchTerms(query string) []string {
	words := strings.Fields(strings.ToLower(query))
	stopWords := map[string]bool{
		"what": true, "when": true, "where": true, "which": true, "with": true, "from": true,
		"that": true, "this": true, "have": true, "about": true, "into": true, "show": true,
		"live": true, "help": true, "explain": true, "tell": true,
	}
	terms := []string{}
	for _, word := range words {
		word = strings.Trim(word, ".,:;!?()[]{}\"'")
		if len(word) < 4 || stopWords[word] {
			continue
		}
		terms = append(terms, word)
	}
	for _, match := range addressPattern.FindAllString(query, -1) {
		terms = append(terms, strings.ToLower(match))
	}
	for _, symbol := range []string{"cUSDT", "cUSDC", "cXAUC", "cEURT", "USDT", "USDC", "WETH", "WETH10", "Mainnet", "bridge", "liquidity", "pool"} {
		if strings.Contains(strings.ToLower(query), strings.ToLower(symbol)) {
			terms = append(terms, strings.ToLower(symbol))
		}
	}
	return uniqueStrings(terms)
}
