package sdlc

import "fmt"

// Execution phase rules: review, audit, QA, merge, archive.

func needsReviewRule() Rule {
	return Rule{
		ID: "needs-review",
		Condition: func(ctx *EvalContext) bool {
			if ctx.Feature.Phase != PhaseReview {
				return false
			}
			art := ctx.Feature.GetArtifact(ArtifactReview)
			return art == nil || art.Status == StatusPending
		},
		Action: ActionReviewCode,
		NextCommand: func(ctx *EvalContext) string {
			return "/review-feature " + ctx.Feature.Slug
		},
		OutputPath: func(ctx *EvalContext) string {
			return ".sdlc/features/" + ctx.Feature.Slug + "/review.md"
		},
	}
}

func reviewHasIssuesRule() Rule {
	return Rule{
		ID: "review-has-issues",
		Condition: func(ctx *EvalContext) bool {
			if ctx.Feature.Phase != PhaseReview {
				return false
			}
			art := ctx.Feature.GetArtifact(ArtifactReview)
			return art != nil && art.Status == StatusNeedsFix
		},
		Action: ActionFixReviewIssues,
		NextCommand: func(ctx *EvalContext) string {
			return "/fix-review-issues " + ctx.Feature.Slug
		},
	}
}

func reviewPassedRule() Rule {
	return Rule{
		ID: "review-passed",
		Condition: func(ctx *EvalContext) bool {
			if ctx.Feature.Phase != PhaseReview {
				return false
			}
			art := ctx.Feature.GetArtifact(ArtifactReview)
			return art != nil && art.Status == StatusPassed
		},
		Action:       ActionTransition,
		TransitionTo: PhaseAudit,
	}
}

func needsAuditRule() Rule {
	return Rule{
		ID: "needs-audit",
		Condition: func(ctx *EvalContext) bool {
			if ctx.Feature.Phase != PhaseAudit {
				return false
			}
			art := ctx.Feature.GetArtifact(ArtifactAudit)
			return art == nil || art.Status == StatusPending
		},
		Action: ActionAuditCode,
		NextCommand: func(ctx *EvalContext) string {
			return "/audit-feature " + ctx.Feature.Slug
		},
		OutputPath: func(ctx *EvalContext) string {
			return ".sdlc/features/" + ctx.Feature.Slug + "/audit.md"
		},
	}
}

func auditHasIssuesRule() Rule {
	return Rule{
		ID: "audit-has-issues",
		Condition: func(ctx *EvalContext) bool {
			if ctx.Feature.Phase != PhaseAudit {
				return false
			}
			art := ctx.Feature.GetArtifact(ArtifactAudit)
			return art != nil && art.Status == StatusNeedsFix
		},
		Action: ActionRemediateAudit,
		NextCommand: func(ctx *EvalContext) string {
			return "/remediate-audit " + ctx.Feature.Slug
		},
	}
}

func auditPassedRule() Rule {
	return Rule{
		ID: "audit-passed",
		Condition: func(ctx *EvalContext) bool {
			if ctx.Feature.Phase != PhaseAudit {
				return false
			}
			art := ctx.Feature.GetArtifact(ArtifactAudit)
			return art != nil && art.Status == StatusPassed
		},
		Action:       ActionTransition,
		TransitionTo: PhaseQA,
	}
}

func needsQARule() Rule {
	return Rule{
		ID: "needs-qa",
		Condition: func(ctx *EvalContext) bool {
			if ctx.Feature.Phase != PhaseQA {
				return false
			}
			art := ctx.Feature.GetArtifact(ArtifactQAResults)
			return art == nil || art.Status == StatusPending
		},
		Action: ActionRunQA,
		NextCommand: func(ctx *EvalContext) string {
			return "/run-qa " + ctx.Feature.Slug
		},
		OutputPath: func(ctx *EvalContext) string {
			return ".sdlc/features/" + ctx.Feature.Slug + "/qa-results.md"
		},
	}
}

func qaHasFailuresRule() Rule {
	return Rule{
		ID: "qa-has-failures",
		Condition: func(ctx *EvalContext) bool {
			if ctx.Feature.Phase != PhaseQA {
				return false
			}
			art := ctx.Feature.GetArtifact(ArtifactQAResults)
			return art != nil && art.Status == StatusFailed
		},
		Action: ActionFixQAFailures,
		NextCommand: func(ctx *EvalContext) string {
			return "/fix-qa-failures " + ctx.Feature.Slug
		},
	}
}

func qaPassedRule() Rule {
	return Rule{
		ID: "qa-passed",
		Condition: func(ctx *EvalContext) bool {
			if ctx.Feature.Phase != PhaseQA {
				return false
			}
			art := ctx.Feature.GetArtifact(ArtifactQAResults)
			return art != nil && art.Status == StatusPassed
		},
		Action:       ActionTransition,
		TransitionTo: PhaseMerge,
	}
}

func needsMergeRule() Rule {
	return Rule{
		ID: "needs-merge",
		Condition: func(ctx *EvalContext) bool {
			return ctx.Feature.Phase == PhaseMerge
		},
		Action: ActionMergeFeature,
		NextCommand: func(ctx *EvalContext) string {
			return "/merge-feature " + ctx.Feature.Slug
		},
	}
}

func archiveFeatureRule() Rule {
	return Rule{
		ID: "archive-feature",
		Condition: func(ctx *EvalContext) bool {
			return ctx.Feature.Phase == PhaseReleased
		},
		Action: ActionArchive,
		NextCommand: func(ctx *EvalContext) string {
			return "/archive-feature " + ctx.Feature.Slug
		},
	}
}

func implementNextTaskRule() Rule {
	return Rule{
		ID: "implement-next-task",
		Condition: func(ctx *EvalContext) bool {
			if ctx.Feature.Phase != PhaseImplementation {
				return false
			}
			next := NextTask(ctx.Feature.Tasks)
			return next != nil
		},
		Action: ActionImplementTask,
		NextCommand: func(ctx *EvalContext) string {
			next := NextTask(ctx.Feature.Tasks)
			if next == nil {
				return ""
			}
			return fmt.Sprintf("/implement-task %s %s", ctx.Feature.Slug, next.ID)
		},
		OutputPath: func(ctx *EvalContext) string {
			return ".sdlc/features/" + ctx.Feature.Slug + "/tasks.md"
		},
		TaskID: func(ctx *EvalContext) string {
			next := NextTask(ctx.Feature.Tasks)
			if next == nil {
				return ""
			}
			return next.ID
		},
	}
}

func implementationCompleteRule() Rule {
	return Rule{
		ID: "implementation-complete",
		Condition: func(ctx *EvalContext) bool {
			return ctx.Feature.Phase == PhaseImplementation && AllTasksComplete(ctx.Feature.Tasks)
		},
		Action:       ActionTransition,
		TransitionTo: PhaseReview,
	}
}
