package db

import (
	"context"
	"time"

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

// EnsureIndexes creates all required indexes. Safe to call on every startup
// (mongo ignores duplicate index creation).
func (c *Client) EnsureIndexes(ctx context.Context) error {
	if err := c.ensureUserIndexes(ctx); err != nil {
		return err
	}
	if err := c.ensureSessionIndexes(ctx); err != nil {
		return err
	}
	return c.ensureLaneIndexes(ctx)
}

func (c *Client) ensureLaneIndexes(ctx context.Context) error {
	_, err := c.Lanes().Indexes().CreateOne(ctx, mongo.IndexModel{
		Keys: bson.D{{Key: "created_by", Value: 1}},
	})
	return err
}

func (c *Client) ensureUserIndexes(ctx context.Context) error {
	_, err := c.Users().Indexes().CreateOne(ctx, mongo.IndexModel{
		Keys:    bson.D{{Key: "username", Value: 1}},
		Options: options.Index().SetUnique(true),
	})
	return err
}

func (c *Client) ensureSessionIndexes(ctx context.Context) error {
	// Unique lookup index on the session token.
	if _, err := c.Sessions().Indexes().CreateOne(ctx, mongo.IndexModel{
		Keys:    bson.D{{Key: "token", Value: 1}},
		Options: options.Index().SetUnique(true),
	}); err != nil {
		return err
	}

	// TTL index: MongoDB automatically deletes session documents after
	// expires_at has passed (checked roughly every 60 s by the reaper).
	expireAfter := int32(0)
	if _, err := c.Sessions().Indexes().CreateOne(ctx, mongo.IndexModel{
		Keys:    bson.D{{Key: "expires_at", Value: 1}},
		Options: options.Index().SetExpireAfterSeconds(expireAfter),
	}); err != nil {
		return err
	}

	return nil
}

// SessionTTL is how long a session stays valid.
const SessionTTL = 24 * time.Hour
