package reactdocs

import (
	"strings"
	"testing"

	"github.com/PuerkitoBio/goquery"
)

const testReferencePageHTML = `
<!DOCTYPE html>
<html>
<body>
<h1>React Reference</h1>

<h2 id="useState">useState</h2>
<p>useState is a React Hook that lets you add a state variable to your component.</p>
<pre><code>const [state, setState] = useState(initialState)</code></pre>

<h2 id="useEffect">useEffect</h2>
<p>useEffect is a React Hook that lets you synchronize a component with an external system.</p>
<pre><code>useEffect(setup, dependencies?)</code></pre>

<h2 id="Suspense">Suspense</h2>
<p>Suspense lets you display a fallback until its children have finished loading.</p>

<h2 id="createContext">createContext</h2>
<p>createContext lets you create a Context that components can provide or read.</p>
<pre><code>createContext(initialValue)</code></pre>
</body>
</html>
`

func TestParseReferencePage(t *testing.T) {
	parser := NewParser()
	ref, err := parser.ParseReferencePage(testReferencePageHTML, "https://react.dev/reference/react")
	if err != nil {
		t.Fatalf("ParseReferencePage failed: %v", err)
	}

	if len(ref.Hooks) == 0 {
		t.Error("Expected at least one hook")
	}

	if len(ref.Components) == 0 {
		t.Error("Expected at least one component")
	}

	if len(ref.APIs) == 0 {
		t.Error("Expected at least one API")
	}
}

func TestExtractHooks(t *testing.T) {
	parser := NewParser()

	doc, err := goquery.NewDocumentFromReader(strings.NewReader(testReferencePageHTML))
	if err != nil {
		t.Fatalf("Failed to parse HTML: %v", err)
	}

	hooks := parser.extractHooks(doc, "https://react.dev/reference/react")

	if len(hooks) == 0 {
		t.Fatal("Expected at least one hook")
	}

	found := false
	for _, h := range hooks {
		if h.Name == "useState" {
			found = true
			if h.Doc == "" {
				t.Error("Expected useState to have documentation")
			}
			break
		}
	}

	if !found {
		t.Error("Expected to find useState hook")
	}
}

func TestExtractComponents(t *testing.T) {
	parser := NewParser()

	doc, err := goquery.NewDocumentFromReader(strings.NewReader(testReferencePageHTML))
	if err != nil {
		t.Fatalf("Failed to parse HTML: %v", err)
	}

	components := parser.extractComponents(doc, "https://react.dev/reference/react")

	found := false
	for _, c := range components {
		if c.Name == "Suspense" {
			found = true
			break
		}
	}

	if !found {
		t.Error("Expected to find Suspense component")
	}
}

func TestResolveURL(t *testing.T) {
	tests := []struct {
		base     string
		href     string
		expected string
	}{
		{"https://react.dev", "/reference/react", "https://react.dev/reference/react"},
		{"https://react.dev", "https://example.com/page", "https://example.com/page"},
	}

	for _, tt := range tests {
		t.Run(tt.href, func(t *testing.T) {
			got := resolveURL(tt.base, tt.href)
			if got != tt.expected {
				t.Errorf("resolveURL(%q, %q) = %q, want %q", tt.base, tt.href, got, tt.expected)
			}
		})
	}
}
