package ux

import (
	"fmt"
	"io"
	"time"
)

// ProgressReporter handles progress reporting for long operations
type ProgressReporter struct {
	writer    io.Writer
	verbose   bool
	startTime time.Time
	steps     []ProgressStep
	current   int
}

// ProgressStep represents a step in a long operation
type ProgressStep struct {
	Name        string
	Description string
	Duration    time.Duration
	Status      StepStatus
}

// StepStatus represents the status of a progress step
type StepStatus string

const (
	StepStatusPending   StepStatus = "pending"
	StepStatusRunning   StepStatus = "running"
	StepStatusCompleted StepStatus = "completed"
	StepStatusFailed    StepStatus = "failed"
	StepStatusSkipped   StepStatus = "skipped"
)

// NewProgressReporter creates a new progress reporter
func NewProgressReporter(writer io.Writer, verbose bool) *ProgressReporter {
	return &ProgressReporter{
		writer:    writer,
		verbose:   verbose,
		startTime: time.Now(),
		steps:     make([]ProgressStep, 0),
		current:   -1,
	}
}

// AddStep adds a new step to the progress reporter
func (p *ProgressReporter) AddStep(name, description string) {
	p.steps = append(p.steps, ProgressStep{
		Name:        name,
		Description: description,
		Status:      StepStatusPending,
	})
}

// StartStep marks the current step as running
func (p *ProgressReporter) StartStep(stepIndex int) {
	if stepIndex < 0 || stepIndex >= len(p.steps) {
		return
	}
	
	p.current = stepIndex
	p.steps[stepIndex].Status = StepStatusRunning
	
	if p.verbose {
		fmt.Fprintf(p.writer, "🔄 Starting: %s\n", p.steps[stepIndex].Description)
	} else {
		fmt.Fprintf(p.writer, "🔄 %s... ", p.steps[stepIndex].Name)
	}
}

// CompleteStep marks the current step as completed
func (p *ProgressReporter) CompleteStep(stepIndex int) {
	if stepIndex < 0 || stepIndex >= len(p.steps) {
		return
	}
	
	p.steps[stepIndex].Status = StepStatusCompleted
	p.steps[stepIndex].Duration = time.Since(p.startTime)
	
	if p.verbose {
		fmt.Fprintf(p.writer, "✅ Completed: %s (took %v)\n", 
			p.steps[stepIndex].Description, p.steps[stepIndex].Duration)
	} else {
		fmt.Fprintf(p.writer, "✅\n")
	}
}

// FailStep marks the current step as failed
func (p *ProgressReporter) FailStep(stepIndex int, err error) {
	if stepIndex < 0 || stepIndex >= len(p.steps) {
		return
	}
	
	p.steps[stepIndex].Status = StepStatusFailed
	p.steps[stepIndex].Duration = time.Since(p.startTime)
	
	if p.verbose {
		fmt.Fprintf(p.writer, "❌ Failed: %s (took %v) - %v\n", 
			p.steps[stepIndex].Description, p.steps[stepIndex].Duration, err)
	} else {
		fmt.Fprintf(p.writer, "❌ (%v)\n", err)
	}
}

// SkipStep marks the current step as skipped
func (p *ProgressReporter) SkipStep(stepIndex int, reason string) {
	if stepIndex < 0 || stepIndex >= len(p.steps) {
		return
	}
	
	p.steps[stepIndex].Status = StepStatusSkipped
	
	if p.verbose {
		fmt.Fprintf(p.writer, "⏭️  Skipped: %s - %s\n", 
			p.steps[stepIndex].Description, reason)
	} else {
		fmt.Fprintf(p.writer, "⏭️  (%s)\n", reason)
	}
}

// PrintSummary prints a summary of all steps
func (p *ProgressReporter) PrintSummary() {
	totalDuration := time.Since(p.startTime)
	
	fmt.Fprintf(p.writer, "\n📊 Build Summary:\n")
	fmt.Fprintf(p.writer, "   Total time: %v\n", totalDuration)
	fmt.Fprintf(p.writer, "   Steps completed: %d/%d\n", 
		p.getCompletedCount(), len(p.steps))
	
	if p.verbose {
		fmt.Fprintf(p.writer, "\n📋 Step Details:\n")
		for i, step := range p.steps {
			status := getStatusEmoji(step.Status)
			fmt.Fprintf(p.writer, "   %d. %s %s", i+1, status, step.Name)
			if step.Duration > 0 {
				fmt.Fprintf(p.writer, " (%v)", step.Duration)
			}
			fmt.Fprintf(p.writer, "\n")
		}
	}
}

// getCompletedCount returns the number of completed steps
func (p *ProgressReporter) getCompletedCount() int {
	count := 0
	for _, step := range p.steps {
		if step.Status == StepStatusCompleted {
			count++
		}
	}
	return count
}

// getStatusEmoji returns an emoji for the step status
func getStatusEmoji(status StepStatus) string {
	switch status {
	case StepStatusPending:
		return "⏳"
	case StepStatusRunning:
		return "🔄"
	case StepStatusCompleted:
		return "✅"
	case StepStatusFailed:
		return "❌"
	case StepStatusSkipped:
		return "⏭️"
	default:
		return "❓"
	}
}

// Simple progress indicators for quick operations

// PrintProgress prints a simple progress indicator
func PrintProgress(writer io.Writer, message string) {
	fmt.Fprintf(writer, "🔄 %s...\n", message)
}

// PrintSuccess prints a success message
func PrintSuccess(writer io.Writer, message string) {
	fmt.Fprintf(writer, "✅ %s\n", message)
}

// PrintWarning prints a warning message
func PrintWarning(writer io.Writer, message string) {
	fmt.Fprintf(writer, "⚠️  %s\n", message)
}

// PrintInfo prints an info message
func PrintInfo(writer io.Writer, message string) {
	fmt.Fprintf(writer, "ℹ️  %s\n", message)
}

// PrintError prints an error message
func PrintError(writer io.Writer, message string) {
	fmt.Fprintf(writer, "❌ %s\n", message)
}

// PrintStep prints a step message with optional details
func PrintStep(writer io.Writer, step, message string, verbose bool) {
	if verbose {
		fmt.Fprintf(writer, "🔄 [%s] %s\n", step, message)
	} else {
		fmt.Fprintf(writer, "🔄 %s\n", message)
	}
}
