package mongo

import (
	"context"
	"errors"
	"fmt"
	"strings"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

const commitStatusCompleted = "completed"

type commitProcessingStateDoc struct {
	RepoID     string    `bson:"repo_id"`
	SnapshotID string    `bson:"snapshot_id"`
	CommitSHA  string    `bson:"commit_sha"`
	ParentSHA  string    `bson:"parent_sha,omitempty"`
	Status     string    `bson:"status"`
	UpdatedAt  time.Time `bson:"updated_at"`
}

// ParentCommitReady reports whether the parent commit delta has been processed.
func (s *Store) ParentCommitReady(ctx context.Context, repoID, snapshotID, parentSHA string) (bool, error) {
	if err := ctx.Err(); err != nil {
		return false, err
	}
	if strings.TrimSpace(parentSHA) == "" {
		return true, nil
	}

	var doc commitProcessingStateDoc
	err := s.collection(collectionCommitProcessingState).FindOne(ctx, bson.M{
		"repo_id":     repoID,
		"snapshot_id": snapshotID,
		"commit_sha":  parentSHA,
		"status":      commitStatusCompleted,
	}).Decode(&doc)
	if err != nil {
		if errors.Is(err, mongo.ErrNoDocuments) {
			return false, nil
		}
		return false, fmt.Errorf("check parent commit state: %w", err)
	}
	return true, nil
}

// MarkCommitCompleted records successful delta processing for ordered commit fan-in.
func (s *Store) MarkCommitCompleted(ctx context.Context, repoID, snapshotID, commitSHA, parentSHA string) error {
	if err := ctx.Err(); err != nil {
		return err
	}

	doc := commitProcessingStateDoc{
		RepoID:     repoID,
		SnapshotID: snapshotID,
		CommitSHA:  commitSHA,
		ParentSHA:  parentSHA,
		Status:     commitStatusCompleted,
		UpdatedAt:  time.Now().UTC(),
	}

	_, err := s.collection(collectionCommitProcessingState).UpdateOne(
		ctx,
		bson.M{
			"repo_id":     repoID,
			"snapshot_id": snapshotID,
			"commit_sha":  commitSHA,
		},
		bson.M{"$set": doc},
		options.Update().SetUpsert(true),
	)
	if err != nil {
		return fmt.Errorf("mark commit completed: %w", err)
	}
	return nil
}
