package kb

import (
	"context"
	"fmt"
	"log/slog"
	"strings"

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

type KBSourceRepositoryInitializeRequest struct {
	Repository repos.RepositoryIdentity
	SourceType string
	Locale     string
}

type KBSourceRepositoryInitializer interface {
	InitializeSourceRepository(context.Context, KBSourceRepositoryInitializeRequest) error
}

func (s AGSHTTPRepositoryStore) InitializeSourceRepository(ctx context.Context, request KBSourceRepositoryInitializeRequest) error {
	owner, repo := sourceRepositoryLogFields(request.Repository)
	sourceType := strings.TrimSpace(request.SourceType)
	locale := presets.NormalizeLocale(request.Locale)
	logAttrs := []any{
		"repo_owner", owner,
		"repo_name", repo,
		"repo_full_name", strings.TrimSpace(request.Repository.FullName),
		"source_type", sourceType,
		"locale", locale,
	}
	if s.Handler == nil && strings.TrimSpace(s.BaseURL) == "" {
		err := invalidArgument("AGS handler or base URL is required to initialize source repository")
		slog.ErrorContext(ctx, "source repository initialization failed", append(logAttrs, "stage", "validate_store", "error", err)...)
		return err
	}
	full := strings.TrimSpace(request.Repository.FullName)
	if full == "" {
		full = strings.TrimSpace(request.Repository.Owner) + "/" + strings.TrimSpace(request.Repository.Name)
	}
	owner, repo, ok := strings.Cut(full, "/")
	if !ok || strings.TrimSpace(owner) == "" || strings.TrimSpace(repo) == "" {
		err := invalidArgument("valid AGS repository is required")
		slog.ErrorContext(ctx, "source repository initialization failed", append(logAttrs, "stage", "validate_repository", "error", err)...)
		return err
	}
	var labels []repositoryLabel
	switch sourceType {
	case "codebase":
		labels = codebaseRepositoryLabels(locale)
	case "file_repository":
		labels = fileRepositoryLabels(locale)
	default:
		slog.InfoContext(ctx, "source repository initialization skipped", append(logAttrs, "stage", "skip_labels", "reason", "unsupported source type")...)
		return nil
	}
	if len(labels) == 0 {
		slog.InfoContext(ctx, "source repository initialization skipped", append(logAttrs, "stage", "skip_labels", "reason", "no labels defined")...)
		return nil
	}
	slog.InfoContext(ctx, "source repository initialization started", append(logAttrs, "stage", "start")...)
	if err := s.ensureRepositoryLabels(ctx, owner, repo, labels); err != nil {
		wrapped := fmt.Errorf("create source repository labels: %w", err)
		slog.ErrorContext(ctx, "source repository initialization failed", append(logAttrs, "stage", "create_labels", "error", wrapped)...)
		return wrapped
	}
	slog.InfoContext(ctx, "source repository initialization completed", append(logAttrs, "stage", "completed", "label_count", len(labels))...)
	return nil
}

func sourceRepositoryLogFields(repository repos.RepositoryIdentity) (owner string, repo string) {
	full := strings.TrimSpace(repository.FullName)
	if full != "" {
		if parsedOwner, parsedRepo, ok := strings.Cut(full, "/"); ok {
			owner = strings.TrimSpace(parsedOwner)
			repo = strings.TrimSpace(parsedRepo)
		}
	}
	if owner == "" {
		owner = strings.TrimSpace(repository.Owner)
	}
	if repo == "" {
		repo = strings.TrimSpace(repository.Name)
	}
	return owner, repo
}
