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

namespace SharepointToolbox.Services.Export;

/// <summary>
/// Exports a flat list of StorageNode objects to a UTF-8 BOM CSV.
/// Compatible with Microsoft Excel (BOM signals UTF-8 encoding).
/// </summary>
public class StorageCsvExportService
{
    public string BuildCsv(IReadOnlyList<StorageNode> nodes)
    {
        var sb = new StringBuilder();

        // Header
        sb.AppendLine("Library,Site,Files,Total Size (MB),Version Size (MB),Last Modified");

        foreach (var node in nodes)
        {
            sb.AppendLine(string.Join(",",
                Csv(node.Name),
                Csv(node.SiteTitle),
                node.TotalFileCount.ToString(),
                FormatMb(node.TotalSizeBytes),
                FormatMb(node.VersionSizeBytes),
                node.LastModified.HasValue
                    ? Csv(node.LastModified.Value.ToString("yyyy-MM-dd"))
                    : string.Empty));
        }

        return sb.ToString();
    }

    public async Task WriteAsync(IReadOnlyList<StorageNode> nodes, string filePath, CancellationToken ct)
    {
        var csv = BuildCsv(nodes);
        await File.WriteAllTextAsync(filePath, csv, new UTF8Encoding(encoderShouldEmitUTF8Identifier: true), ct);
    }

    /// <summary>
    /// Builds a CSV with library details followed by a file-type breakdown section.
    /// </summary>
    public string BuildCsv(IReadOnlyList<StorageNode> nodes, IReadOnlyList<FileTypeMetric> fileTypeMetrics)
    {
        var sb = new StringBuilder();

        // Library details
        sb.AppendLine("Library,Site,Files,Total Size (MB),Version Size (MB),Last Modified");
        foreach (var node in nodes)
        {
            sb.AppendLine(string.Join(",",
                Csv(node.Name),
                Csv(node.SiteTitle),
                node.TotalFileCount.ToString(),
                FormatMb(node.TotalSizeBytes),
                FormatMb(node.VersionSizeBytes),
                node.LastModified.HasValue
                    ? Csv(node.LastModified.Value.ToString("yyyy-MM-dd"))
                    : string.Empty));
        }

        // File type breakdown
        if (fileTypeMetrics.Count > 0)
        {
            sb.AppendLine();
            sb.AppendLine("File Type,Size (MB),File Count");
            foreach (var m in fileTypeMetrics)
            {
                string label = string.IsNullOrEmpty(m.Extension) ? "(no extension)" : m.Extension;
                sb.AppendLine(string.Join(",", Csv(label), FormatMb(m.TotalSizeBytes), m.FileCount.ToString()));
            }
        }

        return sb.ToString();
    }

    public async Task WriteAsync(IReadOnlyList<StorageNode> nodes, IReadOnlyList<FileTypeMetric> fileTypeMetrics, string filePath, CancellationToken ct)
    {
        var csv = BuildCsv(nodes, fileTypeMetrics);
        await File.WriteAllTextAsync(filePath, csv, new UTF8Encoding(encoderShouldEmitUTF8Identifier: true), ct);
    }

    // ── Helpers ───────────────────────────────────────────────────────────────

    private static string FormatMb(long bytes)
        => (bytes / (1024.0 * 1024.0)).ToString("F2");

    /// <summary>RFC 4180 CSV field quoting.</summary>
    private static string Csv(string value)
    {
        if (string.IsNullOrEmpty(value)) return string.Empty;
        if (value.Contains(',') || value.Contains('"') || value.Contains('\n'))
            return $"\"{value.Replace("\"", "\"\"")}\"";
        return value;
    }
}
