using System;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Interactivity;
using ChronoFlow.Controller;
using ChronoFlow.Persistence;
using ChronoFlow.Security;
using ChronoFlow.View.Security;
using Microsoft.Data.Sqlite;
namespace ChronoFlow.View;
///
/// Das Login-Fenster für Benutzer der Anwendung.
/// Es prüft die Anmeldedaten, erzwingt ggf. eine Passwortänderung und startet das Hauptfenster.
///
public partial class LoginWindow : Window
{
private readonly LoginController _loginController;
///
/// Konstruktor – Initialisiert UI und legt bei Bedarf den Standard-Admin an.
///
public LoginWindow()
{
InitializeComponent();
_loginController = new LoginController();
try
{
var service = new SqliteZeiterfassungsService();
service.ErstelleStandardAdmin(); // Falls noch kein Admin vorhanden, wird ein Default-Admin erstellt.
}
catch (SqliteException ex) when (ex.SqliteErrorCode == 5)
{
ErrorText.Text = "⚠️ Die Datenbank ist gesperrt. Bitte schließen Sie andere Programme (z. B. DB Browser for SQLite) und starten Sie die App neu.";
ErrorText.IsVisible = true;
}
catch (Exception ex)
{
ErrorText.Text = $"Fehler beim Initialisieren: {ex.Message}";
ErrorText.IsVisible = true;
}
}
///
/// Wird aufgerufen, wenn der Benutzer auf „Anmelden“ klickt.
///
private async void LoginButton_Click(object? sender, RoutedEventArgs e)
{
var username = UsernameBox.Text?.Trim();
var password = PasswordBox.Text?.Trim();
// Validierung: Felder dürfen nicht leer sein
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
{
ErrorText.Text = "Bitte Benutzername und Passwort eingeben.";
ErrorText.IsVisible = true;
return;
}
SqliteZeiterfassungsService service;
try
{
service = new SqliteZeiterfassungsService();
}
catch (SqliteException ex) when (ex.SqliteErrorCode == 5)
{
ErrorText.Text = "⚠️ Die Datenbank ist gesperrt. Bitte schließen Sie andere Programme und versuchen Sie es erneut.";
ErrorText.IsVisible = true;
return;
}
var benutzerListe = service.LadeAlleBenutzer();
// Benutzer mit eingegebenem Namen (case-insensitive) finden
var matchingUsers = benutzerListe
.Where(u => u.Username.Equals(username, StringComparison.OrdinalIgnoreCase))
.ToList();
if (matchingUsers.Count == 0)
{
ErrorText.Text = "Benutzername nicht gefunden.";
ErrorText.IsVisible = true;
return;
}
if (matchingUsers.Count > 1)
{
ErrorText.Text = "Interner Fehler: Mehrere Benutzer mit gleichem Namen.";
ErrorText.IsVisible = true;
return;
}
var user = matchingUsers.First();
// Passwort-Überprüfung mit Hashing
if (!PasswordHasher.VerifyPassword(password, user.Password))
{
ErrorText.Text = "Falsches Passwort. Bitte erneut versuchen.";
ErrorText.IsVisible = true;
return;
}
// Benutzer muss Passwort ändern? → Dialog anzeigen
if (user.MussPasswortAendern)
{
var dialog = new PasswortAendernDialog(user);
var neuesPasswort = await dialog.ShowDialog(this);
if (!string.IsNullOrEmpty(neuesPasswort))
{
string neuerHash = PasswordHasher.HashPassword(neuesPasswort);
user.Password = neuerHash;
user.MussPasswortAendern = false;
service.UpdateBenutzer(user);
}
else
{
ErrorText.Text = "Sie müssen ein neues Passwort setzen!";
ErrorText.IsVisible = true;
return;
}
}
try
{
// Login-Zeit aktualisieren (für spätere Änderungsbenachrichtigungen)
var vorher = user.LetzterLogin;
user.LetzterLogin = DateTime.Now;
user.VorletzterLogin = vorher;
service.UpdateLoginZeiten(user);
// Hauptfenster öffnen und Login-Fenster schließen
var main = new MainWindow(user);
main.Show();
main.Activate();
Close();
}
catch (SqliteException ex) when (ex.SqliteErrorCode == 5)
{
ErrorText.Text = "⚠️ Datenbank gesperrt. Bitte schließen Sie andere Programme und starten Sie die App neu.";
ErrorText.IsVisible = true;
}
catch (Exception ex)
{
ErrorText.Text = $"Interner Fehler beim Starten des Hauptfensters: {ex.Message}";
ErrorText.IsVisible = true;
}
}
}