using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Logging;
using CredentialManager.Models;
using DataConnection.Interfaces;
using Data_Coupler.Services;
namespace Data_Coupler.Pages;
///
/// Partial class per la gestione di un database come destinazione dati.
/// Consente di selezionare un database di destinazione, scoprirne le tabelle
/// e configurare il mapping dei campi verso la tabella di destinazione.
///
public partial class DataCoupler : ComponentBase
{
// ===== PROPRIETÀ TIPO DESTINAZIONE =====
///
/// Tipo di destinazione: "rest" (default) oppure "database".
/// Controlla quale sezione UI viene mostrata nella card di destra.
///
protected string selectedDestinationType = "rest";
// ===== PROPRIETÀ DATABASE DESTINAZIONE =====
/// Credenziale database selezionata come destinazione
protected string selectedDestinationDatabaseCredential = "";
/// Stato connessione in corso
protected bool isConnectingDestinationDatabase = false;
/// Database di destinazione connesso con successo
protected bool isDestinationDatabaseConnected = false;
/// Messaggio di errore connessione database destinazione
protected string destinationDatabaseErrorMessage = "";
/// Nomi delle tabelle disponibili nel database di destinazione
protected List destAvailableTableNames = new();
/// Schema dettagliato per tabella di destinazione (caricato on-demand)
protected Dictionary> destDatabaseTables = new();
/// Tabella di destinazione selezionata
protected string selectedDestinationTable = "";
/// Termine di ricerca per filtrare le tabelle di destinazione
protected string destDatabaseSearchTerm = "";
/// Database manager per il database di destinazione
protected IDatabaseManager? currentDestinationDatabaseManager = null;
// ===== METODI DATABASE DESTINAZIONE =====
///
/// Gestisce il cambio del tipo di destinazione (rest / database)
///
protected void OnDestinationTypeChanged(ChangeEventArgs e)
{
var newType = e.Value?.ToString() ?? "rest";
if (newType == selectedDestinationType)
return;
selectedDestinationType = newType;
// Reset lo stato della destinazione precedente
ResetDestinationState();
if (newType == "database")
{
ResetDestinationDatabaseState();
}
// Pulisce i mapping configurati (dipendono dal tipo di destinazione)
ClearAllMappings();
StateHasChanged();
}
///
/// Gestisce il cambio della credenziale database di destinazione
///
protected void OnDestinationDatabaseCredentialChanged(ChangeEventArgs e)
{
selectedDestinationDatabaseCredential = e.Value?.ToString() ?? "";
ResetDestinationDatabaseState();
}
///
/// Resetta lo stato del database di destinazione
///
protected void ResetDestinationDatabaseState()
{
isDestinationDatabaseConnected = false;
destAvailableTableNames.Clear();
destDatabaseTables.Clear();
selectedDestinationTable = "";
destDatabaseSearchTerm = "";
destinationDatabaseErrorMessage = "";
// Rilascia il database manager
if (currentDestinationDatabaseManager != null)
{
try { currentDestinationDatabaseManager.Dispose(); } catch { /* ignore */ }
currentDestinationDatabaseManager = null;
}
}
///
/// Si connette al database di destinazione e carica le tabelle disponibili
///
protected async Task ConnectToDestinationDatabase()
{
if (string.IsNullOrEmpty(selectedDestinationDatabaseCredential))
return;
isConnectingDestinationDatabase = true;
destinationDatabaseErrorMessage = "";
try
{
// Verifica credenziale
var credential = databaseCredentials.FirstOrDefault(c => c.Name == selectedDestinationDatabaseCredential);
if (credential == null)
{
destinationDatabaseErrorMessage = "Credenziale database non trovata";
return;
}
// Crea il database manager
currentDestinationDatabaseManager = await ConnectionFactory.CreateDatabaseManagerAsync(selectedDestinationDatabaseCredential);
// Verifica la connessione
var canConnect = await currentDestinationDatabaseManager.TestConnectionAsync();
if (!canConnect)
{
destinationDatabaseErrorMessage = "Impossibile connettersi al database di destinazione. Verificare le credenziali.";
currentDestinationDatabaseManager.Dispose();
currentDestinationDatabaseManager = null;
return;
}
// Carica i nomi delle tabelle
var tableNames = await currentDestinationDatabaseManager.GetTableNamesAsync();
destAvailableTableNames = tableNames.OrderBy(t => t).ToList();
isDestinationDatabaseConnected = true;
Logger.LogInformation("Database destinazione connesso: {Credential}, {Count} tabelle trovate",
selectedDestinationDatabaseCredential, destAvailableTableNames.Count);
}
catch (Exception ex)
{
destinationDatabaseErrorMessage = $"Errore di connessione: {ex.Message}";
Logger.LogError(ex, "Errore nella connessione al database destinazione: {Credential}", selectedDestinationDatabaseCredential);
if (currentDestinationDatabaseManager != null)
{
try { currentDestinationDatabaseManager.Dispose(); } catch { /* ignore */ }
currentDestinationDatabaseManager = null;
}
}
finally
{
isConnectingDestinationDatabase = false;
StateHasChanged();
}
}
///
/// Seleziona la tabella di destinazione e carica il suo schema
///
protected async Task SelectDestinationTable(string tableName)
{
selectedDestinationTable = tableName;
// Carica lo schema della tabella se non è già disponibile
if (currentDestinationDatabaseManager != null && !destDatabaseTables.ContainsKey(tableName))
{
try
{
Logger.LogInformation("Caricamento schema tabella destinazione: {TableName}", tableName);
var schema = await currentDestinationDatabaseManager.GetTableSchemaAsync(tableName);
destDatabaseTables[tableName] = schema;
Logger.LogInformation("Schema tabella destinazione caricato: {ColumnCount} colonne", schema.Count());
}
catch (Exception ex)
{
Logger.LogError(ex, "Errore nel caricamento schema tabella destinazione {TableName}", tableName);
destinationDatabaseErrorMessage = $"Errore nel caricamento schema: {ex.Message}";
}
}
// Pulisce i mapping quando si cambia tabella
ClearAllMappings();
StateHasChanged();
}
///
/// Restituisce la lista filtrata delle tabelle di destinazione
///
protected IEnumerable GetFilteredDestinationTables()
{
if (string.IsNullOrEmpty(destDatabaseSearchTerm))
return destAvailableTableNames;
return destAvailableTableNames
.Where(t => t.Contains(destDatabaseSearchTerm, StringComparison.OrdinalIgnoreCase));
}
///
/// Aggiorna il termine di ricerca per le tabelle di destinazione
///
protected void FilterDestinationTables(ChangeEventArgs e)
{
destDatabaseSearchTerm = e.Value?.ToString() ?? "";
StateHasChanged();
}
///
/// Pulisce il termine di ricerca per le tabelle di destinazione
///
protected void ClearDestinationTableSearch()
{
destDatabaseSearchTerm = "";
StateHasChanged();
}
///
/// Indica se la configurazione corrente è pronta per il trasferimento verso database
///
protected bool IsDestinationDatabaseReady =>
isDestinationDatabaseConnected &&
!string.IsNullOrEmpty(selectedDestinationTable) &&
currentDestinationDatabaseManager != null;
}