using AuthorBuddy.Web.Data; using AuthorBuddy.Web.Models; using LiteDB; namespace AuthorBuddy.Web.Services; public class SettingsService : ISettingsService { private const string KeyOllamaUrl = "ollama_url"; private const string KeyRagModel = "ollama_rag_model"; private const string KeyStyleModel = "ollama_style_model"; private const string KeySpellingModel = "ollama_spelling_model"; private const string KeyTheme = "theme"; private const string KeyLektorPrompt = "ollama_lektor_prompt"; private const string KeyFactCheckTemplate = "ollama_fact_check"; private const string KeySpellingPrompt = "ollama_spelling_prompt"; private const string KeyAdvocatusDiaboli = "ollama_advocatus_diaboli"; private const string KeyHookFinder = "ollama_hook_finder"; private const string KeyEli5 = "ollama_eli5"; private const string KeyLanguage = "language"; private const string KeyLastProjectId = "last_project_id"; private readonly ILiteDatabase _db; private readonly OllamaSettings _ollamaConfig; private int? _currentUserId; private int? _currentProjectId; public SettingsService(ILiteDatabase db, OllamaSettings ollamaConfig) { _db = db; _ollamaConfig = ollamaConfig; } public int? CurrentProjectId { get => _currentProjectId; set => _currentProjectId = value; } public string? CurrentFilePath { get; set; } public string? PendingAssistantInput { get; set; } public string? PendingAssistantOutput { get; set; } public Task GetLastProjectIdAsync() { var col = _db.GetCollection("settings"); var setting = col.FindOne(s => s.Key == KeyLastProjectId && s.UserId == _currentUserId && s.ProjectId == null); if (setting != null && int.TryParse(setting.Value, out var id)) return Task.FromResult(id); return Task.FromResult(null); } public Task SaveLastProjectIdAsync(int projectId) { var col = _db.GetCollection("settings"); var existing = col.FindOne(s => s.Key == KeyLastProjectId && s.UserId == _currentUserId && s.ProjectId == null); if (existing != null) { existing.Value = projectId.ToString(); col.Update(existing); } else { col.Insert(new SettingEntity { Key = KeyLastProjectId, Value = projectId.ToString(), UserId = _currentUserId, ProjectId = null }); } return Task.CompletedTask; } private string? GetSetting(string key, int? userId, int? projectId) { var col = _db.GetCollection("settings"); var matches = col.Find(s => s.Key == key && (s.UserId == userId || s.UserId == null) && (s.ProjectId == projectId || s.ProjectId == null)); return matches .OrderByDescending(s => s.UserId != null) .ThenByDescending(s => s.ProjectId != null) .FirstOrDefault()?.Value; } private string? Get(string key) { return GetSetting(key, _currentUserId, null); } private void Set(string key, string value) { var col = _db.GetCollection("settings"); var existing = col.FindOne(s => s.Key == key && s.UserId == _currentUserId && s.ProjectId == null); if (existing != null) { existing.Value = value; col.Update(existing); } else { col.Insert(new SettingEntity { Key = key, Value = value, UserId = _currentUserId, ProjectId = null }); } } public Task GetOllamaUrlAsync() => Task.FromResult(Get(KeyOllamaUrl)); public Task GetRagModelAsync() => Task.FromResult(Get(KeyRagModel)); public Task GetStyleModelAsync() => Task.FromResult(Get(KeyStyleModel)); public Task GetLektorSystemPromptAsync() => Task.FromResult(Get(KeyLektorPrompt)); public Task GetFactCheckTemplateAsync() => Task.FromResult(Get(KeyFactCheckTemplate)); public Task GetSpellingPromptAsync() => Task.FromResult(Get(KeySpellingPrompt)); public Task GetSpellingModelAsync() => Task.FromResult(Get(KeySpellingModel)); public Task GetAdvocatusDiaboliPromptAsync() => Task.FromResult(Get(KeyAdvocatusDiaboli)); public Task GetHookFinderPromptAsync() => Task.FromResult(Get(KeyHookFinder)); public Task GetEli5PromptAsync() => Task.FromResult(Get(KeyEli5)); public Task GetThemeAsync() => Task.FromResult(Get(KeyTheme)); public Task GetLanguageAsync() => Task.FromResult(Get(KeyLanguage)); public Task SaveLanguageAsync(string language) { Set(KeyLanguage, language); _ollamaConfig.Language = language; return Task.CompletedTask; } public Task SaveOllamaUrlAsync(string url) { Set(KeyOllamaUrl, url); _ollamaConfig.OllamaUrl = url; return Task.CompletedTask; } public Task SaveRagModelAsync(string model) { Set(KeyRagModel, model); _ollamaConfig.EmbedModel = model; return Task.CompletedTask; } public Task SaveStyleModelAsync(string model) { Set(KeyStyleModel, model); _ollamaConfig.StyleModel = model; return Task.CompletedTask; } public Task SaveLektorSystemPromptAsync(string prompt) { Set(KeyLektorPrompt, prompt); _ollamaConfig.LektorSystemPrompt = prompt; return Task.CompletedTask; } public Task SaveFactCheckTemplateAsync(string prompt) { Set(KeyFactCheckTemplate, prompt); _ollamaConfig.FactCheckTemplate = prompt; return Task.CompletedTask; } public Task SaveSpellingPromptAsync(string prompt) { Set(KeySpellingPrompt, prompt); _ollamaConfig.SpellingPrompt = prompt; return Task.CompletedTask; } public Task SaveSpellingModelAsync(string model) { Set(KeySpellingModel, model); _ollamaConfig.SpellingModel = model; return Task.CompletedTask; } public Task SaveAdvocatusDiaboliPromptAsync(string prompt) { Set(KeyAdvocatusDiaboli, prompt); _ollamaConfig.AdvocatusDiaboliPrompt = prompt; return Task.CompletedTask; } public Task SaveHookFinderPromptAsync(string prompt) { Set(KeyHookFinder, prompt); _ollamaConfig.HookFinderPrompt = prompt; return Task.CompletedTask; } public Task SaveEli5PromptAsync(string prompt) { Set(KeyEli5, prompt); _ollamaConfig.Eli5Prompt = prompt; return Task.CompletedTask; } public Task SaveThemeAsync(string theme) { Set(KeyTheme, theme); return Task.CompletedTask; } public Task> GetUsersAsync() { var col = _db.GetCollection("users"); return Task.FromResult(col.FindAll().ToList()); } public Task GetCurrentUserAsync() { var col = _db.GetCollection("users"); var user = col.FindOne(u => u.IsCurrent); return Task.FromResult(user ?? col.FindAll().First()); } public Task SetCurrentUserAsync(int userId) { var col = _db.GetCollection("users"); var users = col.FindAll().ToList(); foreach (var u in users) { u.IsCurrent = u.Id == userId; col.Update(u); } _currentUserId = userId; return Task.CompletedTask; } public Task CreateUserAsync(string name) { var col = _db.GetCollection("users"); var user = new UserEntity { Name = name }; col.Insert(user); return Task.FromResult(user); } public Task LoadProjectSettingsAsync() { var settings = _db.GetCollection("settings"); var entries = new (string Key, Action Setter)[] { (KeyOllamaUrl, val => _ollamaConfig.OllamaUrl = val), (KeyRagModel, val => _ollamaConfig.EmbedModel = val), (KeyStyleModel, val => _ollamaConfig.StyleModel = val), (KeySpellingModel, val => _ollamaConfig.SpellingModel = val), (KeyTheme, val => _ollamaConfig.Theme = val), (KeyLektorPrompt, val => _ollamaConfig.LektorSystemPrompt = val), (KeyFactCheckTemplate, val => _ollamaConfig.FactCheckTemplate = val), (KeySpellingPrompt, val => _ollamaConfig.SpellingPrompt = val), (KeyAdvocatusDiaboli, val => _ollamaConfig.AdvocatusDiaboliPrompt = val), (KeyHookFinder, val => _ollamaConfig.HookFinderPrompt = val), (KeyEli5, val => _ollamaConfig.Eli5Prompt = val), (KeyLanguage, val => _ollamaConfig.Language = val), }; foreach (var entry in entries) { var val = Get(entry.Key); if (val != null) entry.Setter(val); } return Task.CompletedTask; } public Task InitializeAsync(int projectId = -1) { var users = _db.GetCollection("users"); var settings = _db.GetCollection("settings"); var userExists = users.FindAll().Any(); if (!userExists) { var defaultUser = new UserEntity { Name = "Standardbenutzer", IsCurrent = true }; users.Insert(defaultUser); _currentUserId = defaultUser.Id; } else { var current = users.FindOne(u => u.IsCurrent); _currentUserId = current?.Id ?? users.FindAll().First().Id; } var lang = _ollamaConfig.Language; var entries = new (string Key, string Default)[] { (KeyOllamaUrl, _ollamaConfig.OllamaUrl), (KeyRagModel, _ollamaConfig.StyleModel), (KeyStyleModel, _ollamaConfig.StyleModel), (KeySpellingModel, _ollamaConfig.SpellingModel), (KeyTheme, _ollamaConfig.Theme), (KeyLanguage, lang), (KeyLektorPrompt, lang == "en" ? _ollamaConfig.LektorSystemPromptEn : _ollamaConfig.LektorSystemPrompt), (KeyFactCheckTemplate, lang == "en" ? _ollamaConfig.FactCheckTemplateEn : _ollamaConfig.FactCheckTemplate), (KeySpellingPrompt, lang == "en" ? _ollamaConfig.SpellingPromptEn : _ollamaConfig.SpellingPrompt), (KeyAdvocatusDiaboli, lang == "en" ? _ollamaConfig.AdvocatusDiaboliPromptEn : _ollamaConfig.AdvocatusDiaboliPrompt), (KeyHookFinder, lang == "en" ? _ollamaConfig.HookFinderPromptEn : _ollamaConfig.HookFinderPrompt), (KeyEli5, lang == "en" ? _ollamaConfig.Eli5PromptEn : _ollamaConfig.Eli5Prompt), }; foreach (var entry in entries) { var existing = settings.FindOne(s => s.Key == entry.Key && s.UserId == _currentUserId && s.ProjectId == projectId); if (existing != null) { var val = existing.Value; if (entry.Key == KeyOllamaUrl) _ollamaConfig.OllamaUrl = val; else if (entry.Key == KeyRagModel) _ollamaConfig.EmbedModel = val; else if (entry.Key == KeyStyleModel) _ollamaConfig.StyleModel = val; else if (entry.Key == KeySpellingModel) _ollamaConfig.SpellingModel = val; else if (entry.Key == KeyTheme) _ollamaConfig.Theme = val; else if (entry.Key == KeyLanguage) _ollamaConfig.Language = val; else if (entry.Key == KeyLektorPrompt) _ollamaConfig.LektorSystemPrompt = val; else if (entry.Key == KeyFactCheckTemplate) _ollamaConfig.FactCheckTemplate = val; else if (entry.Key == KeySpellingPrompt) _ollamaConfig.SpellingPrompt = val; else if (entry.Key == KeyAdvocatusDiaboli) _ollamaConfig.AdvocatusDiaboliPrompt = val; else if (entry.Key == KeyHookFinder) _ollamaConfig.HookFinderPrompt = val; else if (entry.Key == KeyEli5) _ollamaConfig.Eli5Prompt = val; } else { settings.Insert(new SettingEntity { Key = entry.Key, Value = entry.Default, UserId = _currentUserId, ProjectId = null }); } } return Task.CompletedTask; } }