package agent

import (
	"fmt"
	"io"
	"strings"
	"sync"

	"github.com/tidbcloud/AgentTeam/internal/core/rewindcaps"
)

// ClaudeDriver drives the local `claude` CLI in stream-json mode.
type ClaudeDriver struct {
	mu                       sync.Mutex
	stdinPipe                io.Writer
	toolCallNames            map[string]string
	sessionID                string
	lastTranscriptUUID       string
	replayRecoveryBoundaries map[string]claudeRecoveryBoundary
	controlWaiters           map[string]chan error
	slashCommandsDisabled    bool
	compactQueued            bool
	compactionInProgress     bool
	compactBoundaryObserved  bool
}

type claudeRecoveryBoundary struct {
	sessionID    string
	boundaryUUID string
}

func (d *ClaudeDriver) PrepareRecoveryPointForMessage(messageID string) (strategy string, recoveryRef string, supported bool, err error) {
	if !rewindcaps.ForRuntime(d.Name()).Supported {
		return "", "", false, nil
	}
	trimmedMessageID := strings.TrimSpace(messageID)
	if trimmedMessageID == "" {
		return "", "", false, nil
	}
	d.mu.Lock()
	sessionID := strings.TrimSpace(d.sessionID)
	boundaryUUID := strings.TrimSpace(d.lastTranscriptUUID)
	if boundary, ok := d.replayRecoveryBoundaries[trimmedMessageID]; ok {
		if strings.TrimSpace(boundary.sessionID) != "" {
			sessionID = strings.TrimSpace(boundary.sessionID)
		}
		boundaryUUID = strings.TrimSpace(boundary.boundaryUUID)
	}
	d.mu.Unlock()
	if sessionID == "" {
		return "", "", true, fmt.Errorf("claude session is not initialized")
	}
	boundaryKind := rewindcaps.RecoveryBoundaryResumeAt
	if boundaryUUID == "" {
		boundaryKind = rewindcaps.RecoveryBoundaryBeforeFirstInput
	}
	ref, err := rewindcaps.EncodeClaudeSessionResumeAtRecoveryRef(sessionID, boundaryUUID, boundaryKind)
	if err != nil {
		return "", "", true, err
	}
	return rewindcaps.StrategyClaudeSessionResumeAt, ref, true, nil
}
