using System.IO;
using System.Text;
using SharepointToolbox.Core.Models;
using SharepointToolbox.Localization;

namespace SharepointToolbox.Services.Export;

/// <summary>
/// Exports SearchResult list to a UTF-8 BOM CSV file.
/// Header matches the column order in SearchHtmlExportService for consistency.
/// </summary>
public class SearchCsvExportService
{
    /// <summary>
    /// Builds the CSV payload. Column order mirrors
    /// <see cref="SearchHtmlExportService.BuildHtml(IReadOnlyList{SearchResult}, ReportBranding?)"/>.
    /// </summary>
    public string BuildCsv(IReadOnlyList<SearchResult> results)
    {
        var T = TranslationSource.Instance;
        var sb = new StringBuilder();

        // Header
        sb.AppendLine($"{T["report.col.file_name"]},{T["report.col.extension"]},{T["report.col.path"]},{T["report.col.created"]},{T["report.col.created_by"]},{T["report.col.modified"]},{T["report.col.modified_by"]},{T["report.col.size_bytes"]}");

        foreach (var r in results)
        {
            sb.AppendLine(string.Join(",",
                Csv(IfEmpty(System.IO.Path.GetFileName(r.Path), r.Title)),
                Csv(r.FileExtension),
                Csv(r.Path),
                r.Created.HasValue      ? Csv(r.Created.Value.ToString("yyyy-MM-dd"))      : string.Empty,
                Csv(r.Author),
                r.LastModified.HasValue ? Csv(r.LastModified.Value.ToString("yyyy-MM-dd")) : string.Empty,
                Csv(r.ModifiedBy),
                r.SizeBytes.ToString()));
        }

        return sb.ToString();
    }

    /// <summary>Writes the CSV to <paramref name="filePath"/> with UTF-8 BOM.</summary>
    public async Task WriteAsync(IReadOnlyList<SearchResult> results, string filePath, CancellationToken ct)
    {
        var csv = BuildCsv(results);
        await ExportFileWriter.WriteCsvAsync(filePath, csv, ct);
    }

    private static string Csv(string value) => CsvSanitizer.EscapeMinimal(value);

    private static string IfEmpty(string? value, string fallback = "")
        => string.IsNullOrEmpty(value) ? fallback : value!;
}
