package runner

import (
	"fmt"
	"path/filepath"
	"strings"

	sharedgithubratelimit "github.com/codex-k8s/kodex/libs/go/domain/githubratelimit"
	webhookdomain "github.com/codex-k8s/kodex/libs/go/domain/webhook"
	"github.com/codex-k8s/kodex/libs/go/mcp/userinteraction"
)

func normalizeTriggerKind(value string) string {
	return string(webhookdomain.NormalizeTriggerKind(value))
}

func hasInteractionResumePayload(rawPayload string) bool {
	return strings.TrimSpace(rawPayload) != ""
}

func hasGitHubRateLimitResumePayload(rawPayload string) bool {
	return strings.TrimSpace(rawPayload) != ""
}

func isInteractionResumeRun(correlationID string) bool {
	return strings.HasPrefix(strings.TrimSpace(correlationID), userinteraction.ResumeCorrelationPrefix)
}

func isGitHubRateLimitResumeRun(correlationID string) bool {
	return strings.HasPrefix(strings.TrimSpace(correlationID), sharedgithubratelimit.ResumeCorrelationPrefix)
}

func shouldRestoreLatestSession(triggerKind string, discussionMode bool, interactionResumePayload string, githubRateLimitResumePayload string) bool {
	if discussionMode || hasInteractionResumePayload(interactionResumePayload) || hasGitHubRateLimitResumePayload(githubRateLimitResumePayload) {
		return true
	}
	return webhookdomain.IsReviseTriggerKind(webhookdomain.NormalizeTriggerKind(triggerKind))
}

func normalizeRuntimeMode(value string) string {
	if strings.EqualFold(strings.TrimSpace(value), runtimeModeFullEnv) {
		return runtimeModeFullEnv
	}
	return runtimeModeCodeOnly
}

func usesPreparedFullEnvRepository(runtimeMode string) bool {
	return normalizeRuntimeMode(runtimeMode) == runtimeModeFullEnv
}

func runnerRepoDir(runtimeMode string) string {
	if !usesPreparedFullEnvRepository(runtimeMode) {
		return filepath.Join("/workspace", "repo")
	}
	return "/workspace"
}

func gitCleanArgs(runtimeMode string) []string {
	return []string{"clean", "-fdx"}
}

func normalizeTemplateKind(value string, triggerKind string) string {
	if strings.EqualFold(strings.TrimSpace(value), promptTemplateKindDiscussion) {
		return promptTemplateKindDiscussion
	}
	normalizedTrigger := webhookdomain.NormalizeTriggerKind(triggerKind)
	if webhookdomain.IsReviseTriggerKind(normalizedTrigger) {
		return promptTemplateKindRevise
	}
	if strings.EqualFold(strings.TrimSpace(value), promptTemplateKindRevise) {
		return promptTemplateKindRevise
	}
	return promptTemplateKindWork
}

func buildTargetBranch(explicitBranch string, runID string, issueNumber int64, triggerKind string, baseBranch string) string {
	trimmedExplicit := strings.TrimSpace(explicitBranch)
	if trimmedExplicit != "" {
		return trimmedExplicit
	}
	if isAIRepairMainDirectTrigger(triggerKind) {
		base := strings.TrimSpace(baseBranch)
		if base != "" {
			return base
		}
		return "main"
	}
	if issueNumber > 0 {
		return fmt.Sprintf("codex/issue-%d", issueNumber)
	}
	trimmedRunID := strings.TrimSpace(runID)
	if len(trimmedRunID) > 12 {
		trimmedRunID = trimmedRunID[:12]
	}
	return "codex/run-" + trimmedRunID
}

func isAIRepairMainDirectTrigger(triggerKind string) bool {
	return webhookdomain.NormalizeTriggerKind(strings.TrimSpace(triggerKind)) == webhookdomain.TriggerKindAIRepair
}

func optionalIssueNumber(value int64) *int {
	if value <= 0 {
		return nil
	}
	intValue := int(value)
	return &intValue
}

func optionalInt(value int) *int {
	if value <= 0 {
		return nil
	}
	intValue := value
	return &intValue
}
