package webterm

import (
	"github.com/rcarmo/webterm/internal/terminalstate"
)

type SessionConnector interface {
	OnData(data []byte)
	OnBinary(payload []byte)
	OnMeta(meta map[string]any)
	OnClose()
}

type Session interface {
	Open(width, height int) error
	Start(connector SessionConnector) error
	Close() error
	Wait() error
	SetTerminalSize(width, height int) error
	SendBytes(data []byte) bool
	SendMeta(meta map[string]any) bool
	IsRunning() bool
	GetReplayBuffer() []byte
	GetScreenSnapshot() terminalstate.Snapshot
	ForceRedraw() error
	UpdateConnector(connector SessionConnector)
	MarkIdle()
}

type noopConnector struct{}

func (noopConnector) OnData([]byte)         {}
func (noopConnector) OnBinary([]byte)       {}
func (noopConnector) OnMeta(map[string]any) {}
func (noopConnector) OnClose()              {}

func dispatchSessionOutput(filtered []byte, tracker *terminalstate.Tracker, replay *ReplayBuffer, connector SessionConnector) {
	if len(filtered) == 0 {
		return
	}
	replay.Add(filtered)
	hasVisualChange := false
	if tracker != nil {
		_ = tracker.Feed(filtered)
		hasVisualChange = tracker.ConsumeActivityChanged()
	}
	connector.OnData(filtered)
	if hasVisualChange {
		connector.OnMeta(map[string]any{"screen_changed": true})
	}
}

func snapshotFromTracker(tracker *terminalstate.Tracker, width, height int) terminalstate.Snapshot {
	if tracker != nil {
		return tracker.Snapshot()
	}
	if height < 0 {
		height = 0
	}
	return terminalstate.Snapshot{
		Width:  width,
		Height: height,
		Buffer: make([][]terminalstate.Cell, height),
	}
}
