package skills

import (
	"testing"
)

func TestMatch(t *testing.T) {
	skills := []SkillMeta{
		{Name: "deploy-service", Description: "Deploy a service via SSH to a remote server", Category: "devops"},
		{Name: "log-analyzer", Description: "Analyze logs for errors and patterns", Category: "analysis"},
		{Name: "health-check", Description: "Check the health of services and systems", Category: "system"},
		{Name: "daily-report", Description: "Generate daily report with metrics", Category: "communication"},
	}

	tests := []struct {
		name          string
		query         string
		expectMatches int
		firstMatch    string // expected first match name
	}{
		{
			name:          "exact match in name",
			query:         "deploy-service",
			expectMatches: 1,
			firstMatch:    "deploy-service",
		},
		{
			name:          "partial match in name",
			query:         "deploy",
			expectMatches: 1,
			firstMatch:    "deploy-service",
		},
		{
			name:          "match in description",
			query:         "analyze logs",
			expectMatches: 2, // log-analyzer and daily-report (both have similar words)
			firstMatch:    "log-analyzer",
		},
		{
			name:          "multiple matches",
			query:         "service",
			expectMatches: 2, // deploy-service and health-check (services)
		},
		{
			name:          "no match",
			query:         "nonexistent",
			expectMatches: 0,
		},
		{
			name:          "empty query",
			query:         "",
			expectMatches: 0,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			matches := Match(tt.query, skills)

			if len(matches) != tt.expectMatches {
				t.Errorf("expected %d matches, got %d", tt.expectMatches, len(matches))
			}

			if tt.firstMatch != "" && len(matches) > 0 {
				if matches[0].Skill.Name != tt.firstMatch {
					t.Errorf("expected first match %q, got %q", tt.firstMatch, matches[0].Skill.Name)
				}
			}

			// Verify confidence is in valid range
			for _, match := range matches {
				if match.Confidence < 0 || match.Confidence > 1 {
					t.Errorf("invalid confidence: %f (must be 0-1)", match.Confidence)
				}
			}

			// Verify matches are sorted by confidence descending
			for i := 1; i < len(matches); i++ {
				if matches[i].Confidence > matches[i-1].Confidence {
					t.Errorf("matches not sorted: %f > %f", matches[i].Confidence, matches[i-1].Confidence)
				}
			}
		})
	}
}

func TestFilterByCategory(t *testing.T) {
	skills := []SkillMeta{
		{Name: "deploy-service", Category: "devops"},
		{Name: "log-analyzer", Category: "analysis"},
		{Name: "health-check", Category: "system"},
		{Name: "daily-report", Category: "communication"},
	}

	tests := []struct {
		name       string
		categories []string
		expectLen  int
	}{
		{
			name:       "no filter (all skills)",
			categories: nil,
			expectLen:  4,
		},
		{
			name:       "single category",
			categories: []string{"devops"},
			expectLen:  1,
		},
		{
			name:       "multiple categories",
			categories: []string{"devops", "system"},
			expectLen:  2,
		},
		{
			name:       "nonexistent category",
			categories: []string{"nonexistent"},
			expectLen:  0,
		},
		{
			name:       "case insensitive",
			categories: []string{"DEVOPS"},
			expectLen:  1,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			filtered := FilterByCategory(skills, tt.categories)

			if len(filtered) != tt.expectLen {
				t.Errorf("expected %d skills, got %d", tt.expectLen, len(filtered))
			}
		})
	}
}
