package commitintel

import (
	"context"

	"bit.admedia.com/scm/ad/adpilot-indexing-commit-intel.com/internal/contracts/events"
	"bit.admedia.com/scm/ad/adpilot-indexing-commit-intel.com/internal/contracts/graph"
	"bit.admedia.com/scm/ad/adpilot-indexing-commit-intel.com/internal/store"
)

// CommitAnalysis represents commit-level intelligence output.
type CommitAnalysis struct {
	AnalysisID       string
	RepoID           string
	SnapshotID       string
	CommitSHA        string
	BaseCommitSHA    string
	ImpactedSymbols  []string
	ChangedFiles     []string
	Summary          string
	RelatedDocChunks []string
	Status           string
}

// EventPublisher defines Redis Stream publisher boundaries.
type EventPublisher interface {
	PublishCommitAnalysisReady(ctx context.Context, event events.CommitAnalysisReadyEvent) error
}

// ArtifactReader loads graph artifacts and deltas from storage.
type ArtifactReader interface {
	LoadArtifactByURI(ctx context.Context, artifactURI string) (graph.Artifact, error)
	LoadDeltaByURI(ctx context.Context, deltaURI string) (graph.Delta, error)
}

// ServiceOption configures optional commit intelligence dependencies.
type ServiceOption func(*Service)

// WithAnalysisWriter wires Mongo-backed analysis persistence.
func WithAnalysisWriter(writer AnalysisWriter) ServiceOption {
	return func(s *Service) {
		s.analysisWriter = writer
	}
}

// WithIndexingRunUpdater wires cross-DB indexing run stage updates.
func WithIndexingRunUpdater(updater IndexingRunUpdater) ServiceOption {
	return func(s *Service) {
		s.indexingRuns = updater
	}
}

// Service coordinates commit intelligence workflows.
type Service struct {
	events         EventPublisher
	reader         ArtifactReader
	analyzer       ImpactAnalyzer
	jobs           *store.AnalysisStore
	analysisWriter AnalysisWriter
	indexingRuns   IndexingRunUpdater
}

// NewService wires commit intelligence dependencies.
func NewService(
	events EventPublisher,
	reader ArtifactReader,
	analyzer ImpactAnalyzer,
	jobs *store.AnalysisStore,
	opts ...ServiceOption,
) *Service {
	svc := &Service{
		events:   events,
		reader:   reader,
		analyzer: analyzer,
		jobs:     jobs,
	}
	for _, opt := range opts {
		opt(svc)
	}
	return svc
}

// Jobs exposes the in-memory analysis job store (for debug APIs in TW-75).
func (s *Service) Jobs() *store.AnalysisStore {
	return s.jobs
}

func (s *Service) Status() string {
	return "idle"
}

func (s *Service) markJobFailed(jobID, message string) {
	if s.jobs != nil {
		s.jobs.MarkFailed(jobID, message)
	}
}
