// Package capture provides screen capture from various sources.
//
// Supports capturing from:
// - Local window (by title or handle)
// - VM display (VNC, Spice, or VM window on host)
// - Full screen / monitor region
//
// The capture interface is source-agnostic — the engine doesn't care
// where the frames come from.
package capture

import (
	"image"
	"time"
)

// Region defines a rectangular area to capture.
type Region struct {
	X, Y, Width, Height int
}

// Source represents a capture source (window, VM, screen, etc.)
type Source interface {
	// Name returns a human-readable description of the source.
	Name() string

	// Capture grabs a single frame.
	Capture() (image.Image, error)

	// CaptureRegion grabs a sub-region of the source.
	CaptureRegion(r Region) (image.Image, error)

	// Size returns the source dimensions.
	Size() (width, height int)

	// Close releases resources.
	Close() error
}

// Stats tracks capture performance metrics.
type Stats struct {
	FrameCount   uint64
	AvgCaptureMs float64
	FPS          float64
	LastCapture  time.Time
}

// Manager handles screen capture with performance tracking.
type Manager struct {
	source Source
	stats  Stats
}

// NewManager creates a capture manager with the given source.
func NewManager(source Source) *Manager {
	return &Manager{source: source}
}

// Capture grabs a frame and updates performance stats.
func (m *Manager) Capture() (image.Image, error) {
	start := time.Now()
	frame, err := m.source.Capture()
	if err != nil {
		return nil, err
	}

	elapsed := time.Since(start)
	m.stats.FrameCount++
	m.stats.LastCapture = start

	// Rolling average
	alpha := 0.1
	ms := float64(elapsed.Microseconds()) / 1000.0
	if m.stats.FrameCount == 1 {
		m.stats.AvgCaptureMs = ms
	} else {
		m.stats.AvgCaptureMs = m.stats.AvgCaptureMs*(1-alpha) + ms*alpha
	}
	if m.stats.AvgCaptureMs > 0 {
		m.stats.FPS = 1000.0 / m.stats.AvgCaptureMs
	}

	return frame, nil
}

// CaptureRegion grabs a sub-region.
func (m *Manager) CaptureRegion(r Region) (image.Image, error) {
	return m.source.CaptureRegion(r)
}

// Stats returns current capture performance stats.
func (m *Manager) Stats() Stats {
	return m.stats
}

// Close releases the capture source.
func (m *Manager) Close() error {
	return m.source.Close()
}

// Source returns the underlying capture source.
func (m *Manager) Source() Source {
	return m.source
}

// Size returns the source dimensions.
func (m *Manager) Size() (width, height int) {
	return m.source.Size()
}

// SetSource swaps the capture source.
// This is useful for development when uploading new screenshots.
func (m *Manager) SetSource(newSource Source) error {
	// Close the old source
	if m.source != nil {
		if err := m.source.Close(); err != nil {
			// Log but don't fail - we still want to switch sources
			// log.Printf("Warning: failed to close old capture source: %v", err)
		}
	}
	
	// Switch to new source
	m.source = newSource
	
	// Reset stats for the new source
	m.stats = Stats{}
	
	return nil
}
