package task

import (
	"context"
	"encoding/json"
	"fmt"
	"log/slog"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"github.com/iomodo/staff/git"
	"github.com/iomodo/staff/llm"
	"github.com/iomodo/staff/tm"
	"golang.org/x/text/cases"
	"golang.org/x/text/language"
)

// SubtaskService handles subtask generation and management
type SubtaskService struct {
	llmProvider  llm.LLMProvider
	taskManager  tm.TaskManager
	agentRoles   []string                // Available agent roles for assignment
	prProvider   git.PullRequestProvider // GitHub PR provider
	githubOwner  string
	githubRepo   string
	cloneManager *git.CloneManager
	logger       *slog.Logger
}

// NewSubtaskService creates a new subtask service
func NewSubtaskService(provider llm.LLMProvider, taskManager tm.TaskManager, agentRoles []string, prProvider git.PullRequestProvider, githubOwner, githubRepo string, cloneManager *git.CloneManager, logger *slog.Logger) *SubtaskService {
	if logger == nil {
		logger = slog.Default()
	}
	return &SubtaskService{
		llmProvider:  provider,
		taskManager:  taskManager,
		agentRoles:   agentRoles,
		prProvider:   prProvider,
		githubOwner:  githubOwner,
		githubRepo:   githubRepo,
		cloneManager: cloneManager,
		logger:       logger,
	}
}

// ShouldGenerateSubtasks asks LLM whether a task needs subtasks based on existing agents
func (s *SubtaskService) ShouldGenerateSubtasks(ctx context.Context, task *tm.Task) (*tm.SubtaskDecision, error) {
	prompt := s.buildSubtaskDecisionPrompt(task)

	req := llm.ChatCompletionRequest{
		Model: "gpt-4",
		Messages: []llm.Message{
			{
				Role:    llm.RoleSystem,
				Content: s.getSubtaskDecisionSystemPrompt(),
			},
			{
				Role:    llm.RoleUser,
				Content: prompt,
			},
		},
		MaxTokens:   &[]int{1000}[0],
		Temperature: &[]float64{0.3}[0],
	}

	resp, err := s.llmProvider.ChatCompletion(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("LLM decision failed: %w", err)
	}

	if len(resp.Choices) == 0 {
		return nil, fmt.Errorf("no response from LLM")
	}

	// Parse the LLM response
	decision, err := s.parseSubtaskDecision(resp.Choices[0].Message.Content)
	if err != nil {
		return nil, fmt.Errorf("failed to parse LLM decision: %w", err)
	}

	return decision, nil
}

// AnalyzeTaskForSubtasks uses LLM to analyze a task and propose subtasks
func (s *SubtaskService) AnalyzeTaskForSubtasks(ctx context.Context, task *tm.Task) (*tm.SubtaskAnalysis, error) {
	prompt := s.buildSubtaskAnalysisPrompt(task)

	req := llm.ChatCompletionRequest{
		Model: "gpt-4",
		Messages: []llm.Message{
			{
				Role:    llm.RoleSystem,
				Content: s.getSubtaskAnalysisSystemPrompt(),
			},
			{
				Role:    llm.RoleUser,
				Content: prompt,
			},
		},
		MaxTokens:   &[]int{4000}[0],
		Temperature: &[]float64{0.3}[0],
	}

	resp, err := s.llmProvider.ChatCompletion(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("LLM analysis failed: %w", err)
	}

	if len(resp.Choices) == 0 {
		return nil, fmt.Errorf("no response from LLM")
	}

	// Parse the LLM response
	analysis, err := s.parseSubtaskAnalysis(resp.Choices[0].Message.Content, task.ID)
	if err != nil {
		return nil, fmt.Errorf("failed to parse LLM response: %w", err)
	}

	return analysis, nil
}

// getSubtaskDecisionSystemPrompt returns the system prompt for subtask decision
func (s *SubtaskService) getSubtaskDecisionSystemPrompt() string {
	availableRoles := strings.Join(s.agentRoles, ", ")

	return fmt.Sprintf(`You are an expert project manager and task analyst. Your job is to determine whether a task needs to be broken down into subtasks.

Currently available team roles and their capabilities: %s

When evaluating a task, consider:
1. Task complexity and scope
2. Whether multiple specialized skills are needed
3. If the task can be completed by a single agent with current capabilities
4. Whether new agent roles might be needed for specialized skills

Respond with a JSON object in this exact format:
{
  "needs_subtasks": true/false,
  "reasoning": "Clear explanation of why subtasks are or aren't needed",
  "complexity_score": 5,
  "required_skills": ["skill1", "skill2", "skill3"]
}

Complexity score should be 1-10 where:
- 1-3: Simple tasks that can be handled by one agent
- 4-6: Moderate complexity, might benefit from subtasks
- 7-10: Complex tasks that definitely need breaking down

Required skills should list all technical/domain skills needed to complete the task.`, availableRoles)
}

// getSubtaskAnalysisSystemPrompt returns the system prompt for subtask analysis
func (s *SubtaskService) getSubtaskAnalysisSystemPrompt() string {
	availableRoles := strings.Join(s.agentRoles, ", ")

	return fmt.Sprintf(`You are an expert project manager and technical architect. Your job is to analyze complex tasks and break them down into well-defined subtasks that can be assigned to specialized team members.

Currently available team roles: %s

When analyzing a task, you should:
1. Understand the task requirements and scope
2. Break it down into logical, manageable subtasks
3. Assign each subtask to the most appropriate team role OR propose creating new agents
4. Estimate effort and identify dependencies
5. Provide a clear execution strategy

If you need specialized skills not covered by existing roles, propose new agent creation.

Respond with a JSON object in this exact format:
{
  "analysis_summary": "Brief analysis of the task and approach",
  "subtasks": [
    {
      "title": "Subtask title",
      "description": "Detailed description of what needs to be done",
      "priority": "high|medium|low",
      "assigned_to": "role_name",
      "estimated_hours": 8,
      "dependencies": ["subtask_index_1", "subtask_index_2"],
      "required_skills": ["skill1", "skill2"]
    }
  ],
  "agent_creations": [
    {
      "role": "new_role_name",
      "skills": ["specialized_skill1", "specialized_skill2"],
      "description": "Description of what this agent does",
      "justification": "Why this new agent is needed"
    }
  ],
  "recommended_approach": "High-level strategy for executing these subtasks",
  "estimated_total_hours": 40,
  "risk_assessment": "Potential risks and mitigation strategies"
}

For existing roles, use: %s
For new agents, propose appropriate role names and skill sets.
Dependencies should reference subtask indices (e.g., ["0", "1"] means depends on first and second subtasks).`, availableRoles, availableRoles)
}

// buildSubtaskDecisionPrompt creates the user prompt for subtask decision
func (s *SubtaskService) buildSubtaskDecisionPrompt(task *tm.Task) string {
	return fmt.Sprintf(`Please evaluate whether the following task needs to be broken down into subtasks:

**Task Title:** %s

**Description:** %s

**Priority:** %s

**Current Status:** %s

Consider:
- Can this be completed by a single agent with existing capabilities?
- Does it require multiple specialized skills?
- Is the scope too large for one person?
- Are there logical components that could be parallelized?

Provide your decision in the JSON format specified in the system prompt.`,
		task.Title,
		task.Description,
		task.Priority,
		task.Status)
}

// buildSubtaskAnalysisPrompt creates the user prompt for LLM analysis
func (s *SubtaskService) buildSubtaskAnalysisPrompt(task *tm.Task) string {
	return fmt.Sprintf(`Please analyze the following task and break it down into subtasks:

**Task Title:** %s

**Description:** %s

**Priority:** %s

**Current Status:** %s

Please analyze this task and provide a detailed breakdown into subtasks. Consider:
- Technical complexity and requirements
- Logical task dependencies 
- Appropriate skill sets needed for each subtask
- Risk factors and potential blockers
- Estimated effort for each component

Provide the analysis in the JSON format specified in the system prompt.`,
		task.Title,
		task.Description,
		task.Priority,
		task.Status)
}

// parseSubtaskDecision parses the LLM response into a SubtaskDecision struct
func (s *SubtaskService) parseSubtaskDecision(response string) (*tm.SubtaskDecision, error) {
	// Try to extract JSON from the response
	jsonStart := strings.Index(response, "{")
	jsonEnd := strings.LastIndex(response, "}")

	if jsonStart == -1 || jsonEnd == -1 {
		return nil, fmt.Errorf("no JSON found in LLM response")
	}

	jsonStr := response[jsonStart : jsonEnd+1]

	var decision tm.SubtaskDecision
	if err := json.Unmarshal([]byte(jsonStr), &decision); err != nil {
		return nil, fmt.Errorf("failed to unmarshal JSON: %w", err)
	}

	return &decision, nil
}

// parseSubtaskAnalysis parses the LLM response into a SubtaskAnalysis struct
func (s *SubtaskService) parseSubtaskAnalysis(response string, parentTaskID string) (*tm.SubtaskAnalysis, error) {
	// Try to extract JSON from the response (LLM might wrap it in markdown)
	jsonStart := strings.Index(response, "{")
	jsonEnd := strings.LastIndex(response, "}")

	if jsonStart == -1 || jsonEnd == -1 {
		return nil, fmt.Errorf("no JSON found in LLM response")
	}

	jsonStr := response[jsonStart : jsonEnd+1]

	var rawAnalysis struct {
		AnalysisSummary string `json:"analysis_summary"`
		Subtasks        []struct {
			Title          string   `json:"title"`
			Description    string   `json:"description"`
			Priority       string   `json:"priority"`
			AssignedTo     string   `json:"assigned_to"`
			EstimatedHours int      `json:"estimated_hours"`
			Dependencies   []string `json:"dependencies"`
			RequiredSkills []string `json:"required_skills"`
		} `json:"subtasks"`
		AgentCreations      []tm.AgentCreationProposal `json:"agent_creations"`
		RecommendedApproach string                     `json:"recommended_approach"`
		EstimatedTotalHours int                        `json:"estimated_total_hours"`
		RiskAssessment      string                     `json:"risk_assessment"`
	}

	if err := json.Unmarshal([]byte(jsonStr), &rawAnalysis); err != nil {
		return nil, fmt.Errorf("failed to unmarshal JSON: %w", err)
	}

	// Convert to our types
	analysis := &tm.SubtaskAnalysis{
		ParentTaskID:        parentTaskID,
		AnalysisSummary:     rawAnalysis.AnalysisSummary,
		AgentCreations:      rawAnalysis.AgentCreations,
		RecommendedApproach: rawAnalysis.RecommendedApproach,
		EstimatedTotalHours: rawAnalysis.EstimatedTotalHours,
		RiskAssessment:      rawAnalysis.RiskAssessment,
	}

	// Convert subtasks
	for _, st := range rawAnalysis.Subtasks {
		priority := tm.PriorityMedium // default
		switch strings.ToLower(st.Priority) {
		case "high":
			priority = tm.PriorityHigh
		case "low":
			priority = tm.PriorityLow
		}

		subtask := tm.SubtaskProposal{
			Title:          st.Title,
			Description:    st.Description,
			Priority:       priority,
			AssignedTo:     st.AssignedTo,
			EstimatedHours: st.EstimatedHours,
			Dependencies:   st.Dependencies,
			RequiredSkills: st.RequiredSkills,
		}

		analysis.Subtasks = append(analysis.Subtasks, subtask)
	}

	// Validate agent assignments and handle new agent creation
	if err := s.validateAndHandleAgentAssignments(analysis); err != nil {
		s.logger.Warn("Warning during agent assignment handling", slog.String("error", err.Error()))
	}

	return analysis, nil
}

// validateAndHandleAgentAssignments validates assignments and creates agent creation subtasks if needed
func (s *SubtaskService) validateAndHandleAgentAssignments(analysis *tm.SubtaskAnalysis) error {
	// Collect all agent roles that will be available (existing + proposed new ones)
	availableRoles := make(map[string]bool)
	for _, role := range s.agentRoles {
		availableRoles[role] = true
	}

	// Add proposed new agent roles
	for _, agentCreation := range analysis.AgentCreations {
		availableRoles[agentCreation.Role] = true

		// Create a subtask for agent creation
		agentCreationSubtask := tm.SubtaskProposal{
			Title:          fmt.Sprintf("Create %s Agent", cases.Title(language.English).String(agentCreation.Role)),
			Description:    fmt.Sprintf("Create and configure a new %s agent with skills: %s. %s", agentCreation.Role, strings.Join(agentCreation.Skills, ", "), agentCreation.Justification),
			Priority:       tm.PriorityHigh, // Agent creation is high priority
			AssignedTo:     "ceo",           // CEO creates new agents
			EstimatedHours: 4,               // Estimated time to set up new agent
			Dependencies:   []string{},      // No dependencies for agent creation
			RequiredSkills: []string{"agent_configuration", "system_design"},
		}

		// Insert at the beginning so agent creation happens first
		analysis.Subtasks = append([]tm.SubtaskProposal{agentCreationSubtask}, analysis.Subtasks...)

		// Update dependencies to account for the new subtask at index 0
		for i := 1; i < len(analysis.Subtasks); i++ {
			for j, dep := range analysis.Subtasks[i].Dependencies {
				// Convert dependency index and increment by 1
				if depIndex := s.parseDependencyIndex(dep); depIndex >= 0 {
					analysis.Subtasks[i].Dependencies[j] = fmt.Sprintf("%d", depIndex+1)
				}
			}
		}
	}

	// Now validate all assignments against available roles
	defaultRole := "ceo" // fallback role
	if len(s.agentRoles) > 0 {
		defaultRole = s.agentRoles[0]
	}

	for i := range analysis.Subtasks {
		if !availableRoles[analysis.Subtasks[i].AssignedTo] {
			s.logger.Warn("Unknown agent role for subtask, using default",
				slog.String("unknown_role", analysis.Subtasks[i].AssignedTo),
				slog.String("subtask_title", analysis.Subtasks[i].Title),
				slog.String("assigned_role", defaultRole))
			analysis.Subtasks[i].AssignedTo = defaultRole
		}
	}

	return nil
}

// parseDependencyIndex parses a dependency string to an integer index
func (s *SubtaskService) parseDependencyIndex(dep string) int {
	var idx int
	if _, err := fmt.Sscanf(dep, "%d", &idx); err == nil {
		return idx
	}
	return -1 // Invalid dependency format
}

// isValidAgentRole checks if a role is in the available agent roles
func (s *SubtaskService) isValidAgentRole(role string) bool {
	for _, availableRole := range s.agentRoles {
		if availableRole == role {
			return true
		}
	}
	return false
}

// GenerateSubtaskPR creates a PR with the proposed subtasks
func (s *SubtaskService) GenerateSubtaskPR(ctx context.Context, analysis *tm.SubtaskAnalysis) (string, error) {
	if s.prProvider == nil {
		return "", fmt.Errorf("PR provider not configured")
	}

	// Generate branch name for subtask proposal
	branchName := fmt.Sprintf("subtasks/%s-proposal", analysis.ParentTaskID)
	s.logger.Info("Creating subtask PR", slog.String("branch", branchName))

	// Create Git branch and commit subtask proposal
	if err := s.createSubtaskBranch(ctx, analysis, branchName); err != nil {
		return "", fmt.Errorf("failed to create subtask branch: %w", err)
	}

	// Generate PR content
	prContent := s.generateSubtaskPRContent(analysis)
	title := fmt.Sprintf("Subtask Proposal: %s", analysis.ParentTaskID)

	// Validate PR content
	if title == "" {
		return "", fmt.Errorf("PR title cannot be empty")
	}
	if prContent == "" {
		return "", fmt.Errorf("PR description cannot be empty")
	}

	// Determine base branch (try main first, fallback to master)
	baseBranch := s.determineBaseBranch(ctx)
	s.logger.Info("Using base branch", slog.String("base_branch", baseBranch))

	// Create the pull request
	options := git.PullRequestOptions{
		Title:       title,
		Description: prContent,
		HeadBranch:  branchName,
		BaseBranch:  baseBranch,
		Labels:      []string{"subtasks", "proposal", "ai-generated"},
		Draft:       false,
	}

	s.logger.Info("Creating PR with options",
		slog.String("title", options.Title),
		slog.String("head_branch", options.HeadBranch),
		slog.String("base_branch", options.BaseBranch))

	pr, err := s.prProvider.CreatePullRequest(ctx, options)
	if err != nil {
		return "", fmt.Errorf("failed to create PR: %w", err)
	}

	prURL := fmt.Sprintf("https://github.com/%s/%s/pull/%d", s.githubOwner, s.githubRepo, pr.Number)
	s.logger.Info("Generated subtask proposal PR", slog.String("pr_url", prURL))

	return prURL, nil
}

// determineBaseBranch determines the correct base branch (main or master)
func (s *SubtaskService) determineBaseBranch(ctx context.Context) string {
	if s.cloneManager == nil {
		return "main" // default fallback
	}

	// Get clone path to check branches
	clonePath, err := s.cloneManager.GetAgentClonePath("subtask-service")
	if err != nil {
		s.logger.Warn("Failed to get clone path for base branch detection", slog.String("error", err.Error()))
		return "main"
	}

	// Check if main branch exists
	gitCmd := func(args ...string) *exec.Cmd {
		return exec.CommandContext(ctx, "git", append([]string{"-C", clonePath}, args...)...)
	}

	// Try to checkout main branch
	cmd := gitCmd("show-ref", "refs/remotes/origin/main")
	if err := cmd.Run(); err == nil {
		return "main"
	}

	// Try to checkout master branch
	cmd = gitCmd("show-ref", "refs/remotes/origin/master")
	if err := cmd.Run(); err == nil {
		return "master"
	}

	// Default to main if neither can be detected
	s.logger.Warn("Could not determine base branch, defaulting to 'main'")
	return "main"
}

// generateSubtaskFile creates the content for an individual subtask file
func (s *SubtaskService) generateSubtaskFile(subtask tm.SubtaskProposal, taskID, parentTaskID string) string {
	var content strings.Builder

	// Generate YAML frontmatter
	content.WriteString("---\n")
	content.WriteString(fmt.Sprintf("id: %s\n", taskID))
	content.WriteString(fmt.Sprintf("title: %s\n", subtask.Title))
	content.WriteString(fmt.Sprintf("description: %s\n", subtask.Description))
	content.WriteString(fmt.Sprintf("assignee: %s\n", subtask.AssignedTo))
	content.WriteString(fmt.Sprintf("owner_id: %s\n", subtask.AssignedTo))
	content.WriteString(fmt.Sprintf("owner_name: %s\n", subtask.AssignedTo))
	content.WriteString("status: todo\n")
	content.WriteString(fmt.Sprintf("priority: %s\n", strings.ToLower(string(subtask.Priority))))
	content.WriteString(fmt.Sprintf("parent_task_id: %s\n", parentTaskID))
	content.WriteString(fmt.Sprintf("estimated_hours: %d\n", subtask.EstimatedHours))
	content.WriteString(fmt.Sprintf("created_at: %s\n", time.Now().Format(time.RFC3339)))
	content.WriteString(fmt.Sprintf("updated_at: %s\n", time.Now().Format(time.RFC3339)))
	content.WriteString("completed_at: null\n")
	content.WriteString("archived_at: null\n")

	// Add dependencies if any
	if len(subtask.Dependencies) > 0 {
		content.WriteString("dependencies:\n")
		for _, dep := range subtask.Dependencies {
			// Convert dependency index to actual subtask ID
			if depIndex := s.parseDependencyIndex(dep); depIndex >= 0 {
				depTaskID := fmt.Sprintf("%s-subtask-%d", parentTaskID, depIndex+1)
				content.WriteString(fmt.Sprintf("  - %s\n", depTaskID))
			}
		}
	}

	// Add required skills if any
	if len(subtask.RequiredSkills) > 0 {
		content.WriteString("required_skills:\n")
		for _, skill := range subtask.RequiredSkills {
			content.WriteString(fmt.Sprintf("  - %s\n", skill))
		}
	}

	content.WriteString("---\n\n")

	// Add markdown content
	content.WriteString("# Task Description\n\n")
	content.WriteString(fmt.Sprintf("%s\n\n", subtask.Description))

	if subtask.EstimatedHours > 0 {
		content.WriteString("## Estimated Effort\n\n")
		content.WriteString(fmt.Sprintf("**Estimated Hours:** %d\n\n", subtask.EstimatedHours))
	}

	if len(subtask.RequiredSkills) > 0 {
		content.WriteString("## Required Skills\n\n")
		for _, skill := range subtask.RequiredSkills {
			content.WriteString(fmt.Sprintf("- %s\n", skill))
		}
		content.WriteString("\n")
	}

	if len(subtask.Dependencies) > 0 {
		content.WriteString("## Dependencies\n\n")
		content.WriteString("This task depends on the completion of:\n\n")
		for _, dep := range subtask.Dependencies {
			if depIndex := s.parseDependencyIndex(dep); depIndex >= 0 {
				depTaskID := fmt.Sprintf("%s-subtask-%d", parentTaskID, depIndex+1)
				content.WriteString(fmt.Sprintf("- %s\n", depTaskID))
			}
		}
		content.WriteString("\n")
	}

	content.WriteString("## Notes\n\n")
	content.WriteString(fmt.Sprintf("This subtask was generated from parent task: %s\n", parentTaskID))
	content.WriteString("Generated by Staff AI Agent System\n\n")

	return content.String()
}

// updateParentTaskAsCompleted updates the parent task file to mark it as completed
func (s *SubtaskService) updateParentTaskAsCompleted(taskFilePath string, analysis *tm.SubtaskAnalysis) error {
	// Read the existing parent task file
	content, err := os.ReadFile(taskFilePath)
	if err != nil {
		return fmt.Errorf("failed to read parent task file: %w", err)
	}

	taskContent := string(content)

	// Find the YAML frontmatter boundaries
	lines := strings.Split(taskContent, "\n")
	var frontmatterStart, frontmatterEnd int = -1, -1

	for i, line := range lines {
		if line == "---" {
			if frontmatterStart == -1 {
				frontmatterStart = i
			} else {
				frontmatterEnd = i
				break
			}
		}
	}

	if frontmatterStart == -1 || frontmatterEnd == -1 {
		return fmt.Errorf("invalid task file format: missing YAML frontmatter")
	}

	// Update the frontmatter
	now := time.Now().Format(time.RFC3339)
	var updatedLines []string

	// Add lines before frontmatter
	updatedLines = append(updatedLines, lines[:frontmatterStart+1]...)

	// Process frontmatter lines
	for i := frontmatterStart + 1; i < frontmatterEnd; i++ {
		line := lines[i]
		if strings.HasPrefix(line, "status:") {
			updatedLines = append(updatedLines, "status: completed")
		} else if strings.HasPrefix(line, "updated_at:") {
			updatedLines = append(updatedLines, fmt.Sprintf("updated_at: %s", now))
		} else if strings.HasPrefix(line, "completed_at:") {
			updatedLines = append(updatedLines, fmt.Sprintf("completed_at: %s", now))
		} else {
			updatedLines = append(updatedLines, line)
		}
	}

	// Add closing frontmatter and rest of content
	updatedLines = append(updatedLines, lines[frontmatterEnd:]...)

	// Add subtask information to the task description
	if frontmatterEnd+1 < len(lines) {
		// Add subtask information
		subtaskInfo := fmt.Sprintf("\n\n## Subtasks Created\n\nThis task has been broken down into %d subtasks:\n\n", len(analysis.Subtasks))
		for i, subtask := range analysis.Subtasks {
			subtaskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
			subtaskInfo += fmt.Sprintf("- **%s**: %s (assigned to %s)\n", subtaskID, subtask.Title, subtask.AssignedTo)
		}
		subtaskInfo += fmt.Sprintf("\n**Total Estimated Hours:** %d\n", analysis.EstimatedTotalHours)
		subtaskInfo += fmt.Sprintf("**Completed:** %s - Task broken down into actionable subtasks\n", now)

		// Insert subtask info before any existing body content
		updatedContent := strings.Join(updatedLines[:], "\n") + subtaskInfo

		// Write the updated content back to the file
		if err := os.WriteFile(taskFilePath, []byte(updatedContent), 0644); err != nil {
			return fmt.Errorf("failed to write updated parent task file: %w", err)
		}
	}

	s.logger.Info("Updated parent task to completed status", slog.String("task_id", analysis.ParentTaskID))
	return nil
}

// generateSubtaskPRContent creates markdown content for the subtask proposal PR
func (s *SubtaskService) generateSubtaskPRContent(analysis *tm.SubtaskAnalysis) string {
	var content strings.Builder

	content.WriteString(fmt.Sprintf("# Subtasks Created for Task %s\n\n", analysis.ParentTaskID))
	content.WriteString(fmt.Sprintf("This PR creates **%d individual task files** in `/operations/tasks/` ready for agent assignment.\n\n", len(analysis.Subtasks)))
	content.WriteString(fmt.Sprintf("✅ **Parent task `%s` has been marked as completed** - the complex task has been successfully broken down into actionable subtasks.\n\n", analysis.ParentTaskID))
	content.WriteString(fmt.Sprintf("## Analysis Summary\n%s\n\n", analysis.AnalysisSummary))
	content.WriteString(fmt.Sprintf("## Recommended Approach\n%s\n\n", analysis.RecommendedApproach))
	content.WriteString(fmt.Sprintf("**Estimated Total Hours:** %d\n\n", analysis.EstimatedTotalHours))

	// List the created task files
	content.WriteString("## Created Task Files\n\n")
	for i, subtask := range analysis.Subtasks {
		taskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
		content.WriteString(fmt.Sprintf("### %d. `%s.md`\n", i+1, taskID))
		content.WriteString(fmt.Sprintf("- **Title:** %s\n", subtask.Title))
		content.WriteString(fmt.Sprintf("- **Assigned to:** %s\n", subtask.AssignedTo))
		content.WriteString(fmt.Sprintf("- **Priority:** %s\n", subtask.Priority))
		content.WriteString(fmt.Sprintf("- **Estimated Hours:** %d\n", subtask.EstimatedHours))
		content.WriteString(fmt.Sprintf("- **Description:** %s\n\n", subtask.Description))
	}

	if analysis.RiskAssessment != "" {
		content.WriteString(fmt.Sprintf("## Risk Assessment\n%s\n\n", analysis.RiskAssessment))
	}

	content.WriteString("## Proposed Subtasks\n\n")

	for i, subtask := range analysis.Subtasks {
		content.WriteString(fmt.Sprintf("### %d. %s\n", i+1, subtask.Title))
		content.WriteString(fmt.Sprintf("- **Assigned to:** %s\n", subtask.AssignedTo))
		content.WriteString(fmt.Sprintf("- **Priority:** %s\n", subtask.Priority))
		content.WriteString(fmt.Sprintf("- **Estimated Hours:** %d\n", subtask.EstimatedHours))

		if len(subtask.Dependencies) > 0 {
			deps := strings.Join(subtask.Dependencies, ", ")
			content.WriteString(fmt.Sprintf("- **Dependencies:** %s\n", deps))
		}

		content.WriteString(fmt.Sprintf("- **Description:** %s\n\n", subtask.Description))
	}

	content.WriteString("---\n")
	content.WriteString("*Generated by Staff AI Agent System*\n\n")
	content.WriteString("**Instructions:**\n")
	content.WriteString("- Review the proposed subtasks\n")
	content.WriteString("- Approve or request changes\n")
	content.WriteString("- When merged, the subtasks will be automatically created and assigned\n")

	return content.String()
}

// createSubtaskBranch creates a Git branch with subtask proposal content
func (s *SubtaskService) createSubtaskBranch(ctx context.Context, analysis *tm.SubtaskAnalysis, branchName string) error {
	if s.cloneManager == nil {
		return fmt.Errorf("clone manager not configured")
	}

	// Get a temporary clone for creating the subtask branch
	clonePath, err := s.cloneManager.GetAgentClonePath("subtask-service")
	if err != nil {
		return fmt.Errorf("failed to get clone path: %w", err)
	}

	// All Git operations use the clone directory
	gitCmd := func(args ...string) *exec.Cmd {
		return exec.CommandContext(ctx, "git", append([]string{"-C", clonePath}, args...)...)
	}

	// Ensure we're on main branch before creating new branch
	cmd := gitCmd("checkout", "main")
	if err := cmd.Run(); err != nil {
		// Try master branch if main doesn't exist
		cmd = gitCmd("checkout", "master")
		if err := cmd.Run(); err != nil {
			return fmt.Errorf("failed to checkout main/master branch: %w", err)
		}
	}

	// Pull latest changes
	cmd = gitCmd("pull", "origin")
	if err := cmd.Run(); err != nil {
		s.logger.Warn("Failed to pull latest changes", slog.String("error", err.Error()))
	}

	// Delete branch if it exists (cleanup from previous attempts)
	cmd = gitCmd("branch", "-D", branchName)
	_ = cmd.Run() // Ignore error if branch doesn't exist

	// Also delete remote tracking branch if it exists
	cmd = gitCmd("push", "origin", "--delete", branchName)
	_ = cmd.Run() // Ignore error if branch doesn't exist

	// Create and checkout new branch
	cmd = gitCmd("checkout", "-b", branchName)
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("failed to create branch: %w", err)
	}

	// Create individual task files for each subtask
	tasksDir := filepath.Join(clonePath, "operations", "tasks")
	if err := os.MkdirAll(tasksDir, 0755); err != nil {
		return fmt.Errorf("failed to create tasks directory: %w", err)
	}

	var stagedFiles []string

	// Update parent task to mark as completed
	parentTaskFile := filepath.Join(tasksDir, fmt.Sprintf("%s.md", analysis.ParentTaskID))
	if err := s.updateParentTaskAsCompleted(parentTaskFile, analysis); err != nil {
		return fmt.Errorf("failed to update parent task: %w", err)
	}

	// Track parent task file for staging
	parentRelativeFile := filepath.Join("operations", "tasks", fmt.Sprintf("%s.md", analysis.ParentTaskID))
	stagedFiles = append(stagedFiles, parentRelativeFile)
	s.logger.Info("Updated parent task file", slog.String("file", parentRelativeFile))

	// Create a file for each subtask
	for i, subtask := range analysis.Subtasks {
		taskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
		taskFile := filepath.Join(tasksDir, fmt.Sprintf("%s.md", taskID))
		taskContent := s.generateSubtaskFile(subtask, taskID, analysis.ParentTaskID)

		if err := os.WriteFile(taskFile, []byte(taskContent), 0644); err != nil {
			return fmt.Errorf("failed to write subtask file %s: %w", taskID, err)
		}

		// Track file for staging
		relativeFile := filepath.Join("operations", "tasks", fmt.Sprintf("%s.md", taskID))
		stagedFiles = append(stagedFiles, relativeFile)
		s.logger.Info("Created subtask file", slog.String("file", relativeFile))
	}

	// Stage all subtask files
	for _, file := range stagedFiles {
		cmd = gitCmd("add", file)
		if err := cmd.Run(); err != nil {
			return fmt.Errorf("failed to stage file %s: %w", file, err)
		}
	}

	// Commit changes
	commitMsg := fmt.Sprintf("Create %d subtasks for task %s and mark parent as completed\n\nGenerated by Staff AI Agent System\n\nFiles modified:\n- %s.md (marked as completed)\n\nCreated individual task files:\n",
		len(analysis.Subtasks), analysis.ParentTaskID, analysis.ParentTaskID)

	// Add list of created files to commit message
	for i := range analysis.Subtasks {
		taskID := fmt.Sprintf("%s-subtask-%d", analysis.ParentTaskID, i+1)
		commitMsg += fmt.Sprintf("- %s.md\n", taskID)
	}

	if len(analysis.AgentCreations) > 0 {
		commitMsg += fmt.Sprintf("\nProposed %d new agents for specialized skills", len(analysis.AgentCreations))
	}
	cmd = gitCmd("commit", "-m", commitMsg)
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("failed to commit: %w", err)
	}

	// Push branch
	cmd = gitCmd("push", "-u", "origin", branchName)
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("failed to push branch: %w", err)
	}

	s.logger.Info("Created subtask proposal branch", slog.String("branch", branchName))
	return nil
}

// Close cleans up the service
func (s *SubtaskService) Close() error {
	if s.llmProvider != nil {
		return s.llmProvider.Close()
	}
	return nil
}
