package runtimeassembly

import (
	"context"
	"errors"

	database "github.com/nexuscrm/db"
	"github.com/nexuscrm/metadata"
	"github.com/nexuscrm/permissions"
	"github.com/nexuscrm/persistence"
	"github.com/nexuscrm/shared/pkg/models"
)

// PageLayoutRuntime is the process-local current Layout read graph. It uses
// the Runtime database directly and owns no authoring or Catalog lifecycle.
type PageLayoutRuntime struct {
	Engine *PageLayoutEngine
}

type PageLayoutEngine struct {
	metadata    *metadata.MetadataService
	permissions *permissions.PermissionService
}

func NewPageLayoutRuntime(
	connection *database.TiDBConnection,
	permissionService *permissions.PermissionService,
) (*PageLayoutRuntime, error) {
	if connection == nil || connection.DB() == nil || permissionService == nil {
		return nil, errors.New("page Layout runtime requires database and permission owners")
	}
	repository := persistence.NewMetadataRepository(connection.DB())
	metadataService := metadata.NewMetadataService(repository, nil, nil)
	metadataService.SetTransactionManager(persistence.NewTransactionManager(connection))
	return &PageLayoutRuntime{Engine: &PageLayoutEngine{
		metadata: metadataService, permissions: permissionService,
	}}, nil
}

func (engine *PageLayoutEngine) ResolveCurrentPageLayouts(
	ctx context.Context,
	objectID string,
	profileID string,
	roleAncestors []string,
	recordTypeIDs []string,
) (map[string]*models.PageLayout, error) {
	if engine == nil || engine.metadata == nil {
		return nil, errors.New("page Layout runtime is unavailable")
	}
	return engine.metadata.ResolveCurrentPageLayouts(
		ctx, objectID, roleAncestors, profileID, recordTypeIDs,
	)
}

func (engine *PageLayoutEngine) ReadCurrentObjectListFields(
	ctx context.Context,
	objectIDs []string,
) (map[string][]string, error) {
	if engine == nil || engine.metadata == nil {
		return nil, errors.New("page Layout runtime is unavailable")
	}
	return engine.metadata.ReadCurrentObjectListFields(ctx, objectIDs)
}

func (engine *PageLayoutEngine) GetRoleAncestorsAtSecurityEpoch(
	ctx context.Context,
	orgID, roleID string,
	securityEpoch uint64,
) ([]string, error) {
	if engine == nil || engine.permissions == nil {
		return nil, errors.New("page Layout role hierarchy is unavailable")
	}
	return engine.permissions.GetRoleAncestorsAtSecurityEpoch(ctx, orgID, roleID, securityEpoch)
}
