package kb

import (
	"encoding/json"
	"net/url"
	"regexp"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/service/resource/repos"
)

const (
	KBSourceStatusQueued = "queued"
	KBSourceStatusReady  = "ready"
	KBSourceStatusFailed = "failed"

	KBJobTypeGenerateRepoWikiFromCode = "generate_repo_wiki_from_code"

	KBJobStatusQueued    = "queued"
	KBJobStatusRunning   = "running"
	KBJobStatusSucceeded = "succeeded"
	KBJobStatusFailed    = "failed"
	KBJobStatusCancelled = "cancelled"
)

type KBSourceRepositoryCreateInput struct {
	Name             string
	RepoNameOverride string
	Description      string
	DefaultBranch    string
}

type KBSourceRepositoryCreateRequest struct {
	WorkspaceID     string
	KnowledgeBaseID string
	SourceType      string
	SourceName      string
	Repository      repos.RepositoryIdentity
	Create          KBSourceRepositoryCreateInput
	Actor           repos.ResourceRepositoryActor
}

// KBManagedRepositoryCreateRequest provisions hidden MeshX-managed KB repositories
// such as source materializations and source-scoped insights wiki/understanding repos.
type KBManagedRepositoryCreateRequest struct {
	WorkspaceID     string
	KnowledgeBaseID string
	SourceID        string
	SourceType      string
	SourceName      string
	Role            string
	Repository      repos.RepositoryIdentity
	Create          KBSourceRepositoryCreateInput
}

var invalidWikiSlugRunes = regexp.MustCompile(`[^a-z0-9/_-]+`)

func normalizeWikiSlug(value string) string {
	value = strings.ToLower(strings.TrimSpace(value))
	value = strings.Trim(value, "/")
	value = strings.ReplaceAll(value, " ", "-")
	value = invalidWikiSlugRunes.ReplaceAllString(value, "-")
	segments := strings.Split(value, "/")
	out := make([]string, 0, len(segments))
	for _, segment := range segments {
		segment = strings.Trim(segment, "-_")
		if segment == "" || segment == "." || segment == ".." {
			continue
		}
		out = append(out, segment)
	}
	return strings.Join(out, "/")
}

func normalizeLabels(labels []string) []string {
	seen := map[string]struct{}{}
	out := make([]string, 0, len(labels))
	for _, label := range labels {
		label = strings.ToLower(strings.TrimSpace(label))
		if label == "" {
			continue
		}
		if _, ok := seen[label]; ok {
			continue
		}
		seen[label] = struct{}{}
		out = append(out, label)
	}
	return out
}

func kbJSONString(value any) string {
	encoded, err := json.Marshal(value)
	if err != nil {
		return "{}"
	}
	return string(encoded)
}

func escapedWikiSlug(slug string) string {
	return url.PathEscape(strings.TrimSpace(slug))
}
