package core

import (
	"context"

	"github.com/deluan/rest"
	"github.com/navidrome/navidrome/model"
)

// PluginUnloader defines the interface for unloading disabled plugins.
// This is satisfied by plugins.Manager but defined here to avoid import cycles.
type PluginUnloader interface {
	UnloadDisabledPlugins(ctx context.Context)
}

// User provides business logic for user management with plugin coordination.
type User interface {
	NewRepository(ctx context.Context) rest.Repository
}

type userService struct {
	ds            model.DataStore
	pluginManager PluginUnloader
}

// NewUser creates a new User service
func NewUser(ds model.DataStore, pluginManager PluginUnloader) User {
	return &userService{
		ds:            ds,
		pluginManager: pluginManager,
	}
}

// NewRepository returns a REST repository wrapper for user operations.
// The wrapper intercepts Delete operations to coordinate plugin unloading.
func (s *userService) NewRepository(ctx context.Context) rest.Repository {
	repo := s.ds.User(ctx)
	wrapper := &userRepositoryWrapper{
		ctx:            ctx,
		UserRepository: repo,
		pluginManager:  s.pluginManager,
	}
	return wrapper
}

type userRepositoryWrapper struct {
	model.UserRepository
	ctx           context.Context
	pluginManager PluginUnloader
}

// Save implements rest.Persistable by delegating to the underlying repository.
func (r *userRepositoryWrapper) Save(entity any) (string, error) {
	return r.UserRepository.(rest.Persistable).Save(entity)
}

// Update implements rest.Persistable by delegating to the underlying repository.
func (r *userRepositoryWrapper) Update(id string, entity any, cols ...string) error {
	return r.UserRepository.(rest.Persistable).Update(id, entity, cols...)
}

// Delete implements rest.Persistable and coordinates plugin unloading.
func (r *userRepositoryWrapper) Delete(id string) error {
	// The underlying repository Delete handles the database cleanup
	// including calling cleanupPluginUserReferences
	err := r.UserRepository.(rest.Persistable).Delete(id)
	if err != nil {
		return err
	}

	// After successful deletion, check if any plugins were auto-disabled
	// and need to be unloaded from memory
	r.pluginManager.UnloadDisabledPlugins(r.ctx)

	return nil
}
