using LINQtoCSV;
using StockFin.Models;

namespace StockFin;

/// <summary>
/// Service de lecture et de traitement du fichier "Exportation de transactions.csv"
/// au format Trade Republic, à l'aide de LINQtoCSV.
/// </summary>
public class TransactionCsvImporter
{
    /// <summary>
    /// Format Trade Republic : séparateur virgule, décimales avec point, en-têtes en ligne 1.
    /// </summary>
    private static readonly CsvFileDescription FileDescription = new()
    {
        SeparatorChar             = ',',      // Trade Republic utilise la virgule
        FirstLineHasColumnNames   = true,
        FileCultureName           = "en-US",  // Décimales avec point  (ex : "1800.000000")
        EnforceCsvColumnAttribute = true,     // N'utilise que les propriétés annotées [CsvColumn]
        IgnoreUnknownColumns      = true,     // Ignore les colonnes CSV sans propriété mappée
    };

    private readonly CsvContext _csv = new();

    /// <summary>
    /// Lit le fichier CSV et retourne les lignes mappées vers <see cref="TransactionCsvRow"/>.
    /// </summary>
    /// <param name="filePath">Chemin absolu ou relatif vers le fichier CSV.</param>
    /// <returns>Liste des lignes du fichier.</returns>
    /// <exception cref="FileNotFoundException">Si le fichier est introuvable.</exception>
    /// <exception cref="AggregatedException">Si des erreurs de parsing sont rencontrées.</exception>
    public IList<TransactionCsvRow> Read(string filePath)
    {
        if (!File.Exists(filePath))
            throw new FileNotFoundException("Le fichier CSV est introuvable.", filePath);

        return _csv.Read<TransactionCsvRow>(filePath, FileDescription).ToList();
    }

    /// <summary>
    /// Convertit les lignes CSV en entités <see cref="Transaction"/> prêtes à être persistées.
    /// Adaptez le mapping selon les propriétés réelles de votre modèle Transaction.
    /// </summary>
    /// <param name="rows">Lignes lues depuis le CSV.</param>
    public IEnumerable<Transaction> ToTransactions(IList<TransactionCsvRow> rows)
    {
        return rows.Select(MapToTransaction);
    }

    private static Transaction MapToTransaction(TransactionCsvRow row)
    {
        // TODO : adaptez ce mapping aux propriétés réelles de votre modèle Transaction.
        return new Transaction
        {
            // Date     = row.Date ?? row.DateTimeUtc ?? DateTime.UtcNow,
            // Quantity = (int?)row.Shares,
            // Price    = (double?)row.Price,
            // Fees     = (double?)row.Fee,
            // StockId  = ... // à résoudre via row.Symbol ou row.Name
        };
    }
}
