package runtime

import (
	"context"
	"errors"
	"fmt"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/automation/dsl"
	"github.com/tidbcloud/AgentTeam/internal/store/automation"
)

// WikiPublisher publishes staged Markdown pages into an AGS wiki repository.
type WikiPublisher interface {
	PublishWikiPages(ctx context.Context, req WikiPublishRequest) (WikiPublishResult, error)
}

// WikiPublishRequest describes one bounded publish operation from a job workdir.
type WikiPublishRequest struct {
	WorkspaceID    string
	RunID          string
	JobRunID       string
	Repository     string
	SourcePath     string
	Message        string
	Description    string
	Label          string
	MaxPages       int
	DefaultBranch  string
	Visibility     string
	RepositoryKind string
}

// WikiPublishResult summarizes a completed wiki publish.
type WikiPublishResult struct {
	Repository       string
	Pages            int
	Bytes            int64
	IndexedCommitSHA string
	Reconciled       bool
}

func (r *ServerRunner) executePublishWikiStep(ctx context.Context, job automation.AutomationJob, jobRun automation.AutomationJobRun, step dsl.StepSpec, stepIndex int, workDir string) error {
	if r.cfg.WikiPublisher == nil {
		return fmt.Errorf("automation wiki publisher is not configured")
	}
	options, optionErrs := dsl.ParseAgentTeamPublishWikiOptions(step.With)
	if len(optionErrs) > 0 {
		return optionErrs[0]
	}
	sourcePath, err := serverRunnerCheckoutDestination(workDir, options.SourcePath)
	if err != nil {
		return err
	}
	if err := r.appendCheckoutEvent(ctx, job, jobRun, stepIndex, "wiki_publish_started", "Automation wiki publish started", wikiPublishEventMetadata(options.Repository, options.SourcePath, nil)); err != nil {
		return err
	}
	result, err := r.cfg.WikiPublisher.PublishWikiPages(ctx, WikiPublishRequest{
		WorkspaceID:    jobRun.WorkspaceID,
		RunID:          jobRun.RunID,
		JobRunID:       jobRun.ID,
		Repository:     options.Repository,
		SourcePath:     sourcePath,
		Message:        options.Message,
		Description:    options.Description,
		Label:          options.Label,
		MaxPages:       options.MaxPages,
		DefaultBranch:  "main",
		Visibility:     "private",
		RepositoryKind: "automation_preset_wiki",
	})
	if err != nil {
		failedMetadata := wikiPublishEventMetadata(options.Repository, options.SourcePath, nil)
		failedMetadata["error"] = err.Error()
		eventErr := r.appendCheckoutEvent(ctx, job, jobRun, stepIndex, "wiki_publish_failed", "Automation wiki publish failed", failedMetadata)
		if eventErr != nil {
			return errors.Join(fmt.Errorf("automation wiki publish failed: %w", err), eventErr)
		}
		return fmt.Errorf("automation wiki publish failed: %w", err)
	}
	if err := r.appendCheckoutEvent(ctx, job, jobRun, stepIndex, "wiki_publish_succeeded", "Automation wiki publish succeeded", wikiPublishEventMetadata(options.Repository, options.SourcePath, &result)); err != nil {
		return err
	}
	return nil
}

func wikiPublishEventMetadata(repository string, sourcePath string, result *WikiPublishResult) map[string]any {
	sourcePath = strings.TrimSpace(sourcePath)
	if sourcePath == "" {
		sourcePath = "."
	}
	metadata := map[string]any{
		"repository":  strings.TrimSpace(repository),
		"source_path": sourcePath,
	}
	if result == nil {
		return metadata
	}
	metadata["pages"] = result.Pages
	metadata["bytes"] = result.Bytes
	metadata["indexed_commit_sha"] = strings.TrimSpace(result.IndexedCommitSHA)
	metadata["reconciled"] = result.Reconciled
	return metadata
}
