using System.Globalization;
using System.Text;
using ROLAC.API.DTOs.Finance;
using ROLAC.API.Services;
using Xunit;

namespace ROLAC.API.Tests.Services;

public class Form1099FormServiceTests
{
    /// <summary>Stub report service: only GetAnnualSummaryAsync is exercised by the CSV export.</summary>
    private sealed class StubReportService : IForm1099ReportService
    {
        private readonly Form1099SummaryDto _summary;
        public StubReportService(Form1099SummaryDto summary) => _summary = summary;

        public Task<Form1099SummaryDto> GetAnnualSummaryAsync(int taxYear) => Task.FromResult(_summary);
        public Task<List<Form1099BoxDto>> GetBoxesAsync() => throw new NotImplementedException();
        public Task<Form1099RecipientDetailDto?> GetRecipientDetailAsync(int payeeId, int taxYear)
            => throw new NotImplementedException();
    }

    private static Form1099FormService BuildService(Form1099SummaryDto summary) =>
        // IPayee1099Service and AppDbContext are only used by RenderCopyBAsync, not by the CSV path.
        new Form1099FormService(new StubReportService(summary), payees: null!, db: null!);

    [Fact]
    public async Task ExportFilingCsvAsync_WritesHeaderRowPerRecipientAndInvariantNumbers()
    {
        var summary = new Form1099SummaryDto
        {
            TaxYear = 2026,
            Rows =
            {
                new Form1099RecipientRowDto
                {
                    PayeeId = 1, LegalName = "Acme, LLC", TinLast4 = "1234", W9Status = "OnFile",
                    NecTotal = 1234.50m, RentsTotal = 0m, GrandTotal = 1234.50m, MeetsThreshold = true
                },
                new Form1099RecipientRowDto
                {
                    PayeeId = 2, LegalName = "Bob Smith", TinLast4 = "9876", W9Status = "Missing",
                    NecTotal = 100m, RentsTotal = 50m, GrandTotal = 150m, MeetsThreshold = false
                },
            }
        };

        var service = BuildService(summary);
        var (stream, contentType, fileName) = await service.ExportFilingCsvAsync(2026);

        Assert.Equal("text/csv", contentType);
        Assert.Equal("1099-filing-2026.csv", fileName);

        using var reader = new StreamReader(stream, Encoding.UTF8);
        var text = await reader.ReadToEndAsync();
        var lines = text.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);

        // Header + one data line per row.
        Assert.Equal(3, lines.Length);
        Assert.Equal("LegalName,TinLast4,W9Status,Box1_NEC,Box1_Rents,Total,MeetsThreshold", lines[0]);

        // A value containing a comma is quoted.
        Assert.StartsWith("\"Acme, LLC\",1234,OnFile,", lines[1]);

        // Invariant numeric formatting (period decimal separator) and Y/N threshold flag.
        Assert.Contains("1234.50", lines[1]);
        Assert.EndsWith(",Y", lines[1]);
        Assert.EndsWith(",N", lines[2]);

        // Sanity: the period really is the invariant separator regardless of current culture.
        Assert.Equal("1234.50", 1234.50m.ToString(CultureInfo.InvariantCulture));
    }
}
