package store

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

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

	"bountyboard/internal/domain"
)

// GetSettings returns the app settings document, creating defaults on first
// access.
func (s *Store) GetSettings(ctx context.Context) (*domain.AppSettings, error) {
	var st domain.AppSettings
	err := s.DB.Collection("settings").FindOne(ctx, bson.M{"_id": "app"}).Decode(&st)
	if errors.Is(err, mongo.ErrNoDocuments) {
		st = domain.AppSettings{
			ID:                     "app",
			BrandingName:           "Bounty Board",
			DefaultPollIntervalSec: 60,
			DefaultCustomerBudget:  1000,
			UpdatedAt:              time.Now().UTC(),
			Version:                1,
		}
		if _, err := s.DB.Collection("settings").InsertOne(ctx, st); err != nil &&
			!mongo.IsDuplicateKeyError(err) {
			return nil, fmt.Errorf("init settings: %w", err)
		}
		return &st, nil
	}
	if err != nil {
		return nil, fmt.Errorf("get settings: %w", err)
	}
	return &st, nil
}

// PatchSettings applies a partial settings update (not version-raced in the
// UI; last write wins is acceptable for a single admin page).
func (s *Store) PatchSettings(ctx context.Context, set bson.M) (*domain.AppSettings, error) {
	if _, err := s.GetSettings(ctx); err != nil { // ensure the doc exists
		return nil, err
	}
	set["updatedAt"] = time.Now().UTC()
	_, err := s.DB.Collection("settings").UpdateOne(ctx, bson.M{"_id": "app"},
		bson.M{"$set": set, "$inc": bson.M{"version": 1}})
	if err != nil {
		return nil, fmt.Errorf("patch settings: %w", err)
	}
	return s.GetSettings(ctx)
}
