package subtasks

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"
)

// 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", strings.Title(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(fmt.Sprintf("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[:len(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
}