package mongo

import (
	"context"
	"fmt"
	"time"

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

	contractevents "bit.admedia.com/scm/ad/adpilot-indexing-code-parser.com/internal/contracts/events"
)

type codeChunkDoc struct {
	RepoID     string `bson:"repo_id"`
	SnapshotID string `bson:"snapshot_id"`
	CommitSHA  string `bson:"commit_sha"`
	FilePath   string `bson:"file_path"`
	Language   string `bson:"language"`
	ChunkID    string `bson:"chunk_id"`
	SymbolName string `bson:"symbol_name"`
	SymbolType string `bson:"symbol_type"`
	Text       string `bson:"text"`
	StartLine  int    `bson:"start_line"`
	EndLine    int    `bson:"end_line"`
	ArtifactID string `bson:"artifact_id"`
	UpdatedAt  time.Time `bson:"updated_at"`
}

// SaveCodeChunks upserts parsed code chunks for a file.
func (s *Store) SaveCodeChunks(
	ctx context.Context,
	repoID, snapshotID, commitSHA, filePath, language, artifactID string,
	chunks []contractevents.CodeChunk,
) error {
	if err := ctx.Err(); err != nil {
		return err
	}
	if len(chunks) == 0 {
		return nil
	}

	col := s.collection(collectionCodeChunks)
	now := time.Now().UTC()

	for _, chunk := range chunks {
		doc := codeChunkDoc{
			RepoID:     repoID,
			SnapshotID: snapshotID,
			CommitSHA:  commitSHA,
			FilePath:   filePath,
			Language:   language,
			ChunkID:    chunk.ChunkID,
			SymbolName: chunk.SymbolName,
			SymbolType: string(chunk.SymbolType),
			Text:       chunk.Text,
			StartLine:  chunk.StartLine,
			EndLine:    chunk.EndLine,
			ArtifactID: artifactID,
			UpdatedAt:  now,
		}

		_, err := col.UpdateOne(
			ctx,
			bson.M{
				"repo_id":     repoID,
				"snapshot_id": snapshotID,
				"chunk_id":    chunk.ChunkID,
			},
			bson.M{"$set": doc},
			options.Update().SetUpsert(true),
		)
		if err != nil {
			return fmt.Errorf("upsert code chunk %q: %w", chunk.ChunkID, err)
		}
	}
	return nil
}
