package notelinks

import (
	"testing"
)

func TestExtractWikilinks(t *testing.T) {
	tests := []struct {
		name    string
		content string
		want    int
		checks  func(t *testing.T, links []struct{ title, display string; transclusion bool })
	}{
		{
			name:    "no links",
			content: "Just some plain text with [single brackets]",
			want:    0,
		},
		{
			name:    "single link",
			content: "See [[Project Notes]] for details",
			want:    1,
			checks: func(t *testing.T, links []struct{ title, display string; transclusion bool }) {
				if links[0].title != "Project Notes" {
					t.Errorf("title = %q, want %q", links[0].title, "Project Notes")
				}
				if links[0].transclusion {
					t.Error("should not be transclusion")
				}
			},
		},
		{
			name:    "link with display text",
			content: "Check the [[Architecture Doc|arch doc]] here",
			want:    1,
			checks: func(t *testing.T, links []struct{ title, display string; transclusion bool }) {
				if links[0].title != "Architecture Doc" {
					t.Errorf("title = %q", links[0].title)
				}
				if links[0].display != "arch doc" {
					t.Errorf("display = %q", links[0].display)
				}
			},
		},
		{
			name:    "transclusion",
			content: "Embed this: ![[Meeting Notes]]",
			want:    1,
			checks: func(t *testing.T, links []struct{ title, display string; transclusion bool }) {
				if links[0].title != "Meeting Notes" {
					t.Errorf("title = %q", links[0].title)
				}
				if !links[0].transclusion {
					t.Error("should be transclusion")
				}
			},
		},
		{
			name:    "multiple links deduplicated",
			content: "See [[Alpha]] and [[Beta]] and [[Alpha]] again",
			want:    2,
		},
		{
			name:    "case-insensitive dedup",
			content: "See [[Project]] and [[project]]",
			want:    1,
			checks: func(t *testing.T, links []struct{ title, display string; transclusion bool }) {
				if links[0].title != "Project" {
					t.Errorf("title = %q, want first occurrence", links[0].title)
				}
			},
		},
		{
			name:    "mixed links and transclusions",
			content: "Link to [[Alpha]], embed ![[Beta|b]], and [[Gamma]]",
			want:    3,
		},
		{
			name:    "whitespace trimmed",
			content: "See [[ Spaced Title ]] here",
			want:    1,
			checks: func(t *testing.T, links []struct{ title, display string; transclusion bool }) {
				if links[0].title != "Spaced Title" {
					t.Errorf("title = %q, want trimmed", links[0].title)
				}
			},
		},
		{
			name:    "nested brackets ignored",
			content: "Not a link: [[[triple]]] but [[Valid]] is",
			want:    1,
			checks: func(t *testing.T, links []struct{ title, display string; transclusion bool }) {
				if links[0].title != "Valid" {
					t.Errorf("title = %q, want Valid", links[0].title)
				}
			},
		},
		{
			name:    "empty brackets ignored",
			content: "Empty [[]] should not match",
			want:    0,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			links := ExtractWikilinks(tt.content)
			if len(links) != tt.want {
				t.Fatalf("got %d links, want %d", len(links), tt.want)
			}
			if tt.checks != nil {
				simplified := make([]struct{ title, display string; transclusion bool }, len(links))
				for i, l := range links {
					simplified[i] = struct{ title, display string; transclusion bool }{
						title: l.TargetTitle, display: l.DisplayText, transclusion: l.IsTransclusion,
					}
				}
				tt.checks(t, simplified)
			}
		})
	}
}
