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