using SharepointToolbox.Core.Models;
using SharepointToolbox.Services.Export;

namespace SharepointToolbox.Tests.Services.Export;

/// <summary>
/// Tests for PERM-05: CSV export output.
/// These tests reference CsvExportService which will be implemented in Plan 03.
/// Until Plan 03 runs they will fail to compile — that is expected.
/// </summary>
public class CsvExportServiceTests
{
    private static PermissionEntry MakeEntry(
        string objectType, string title, string url,
        bool hasUnique, string users, string userLogins,
        string permissionLevels, string grantedThrough, string principalType) =>
        new(objectType, title, url, hasUnique, users, userLogins, permissionLevels, grantedThrough, principalType);

    [Fact]
    public void BuildCsv_WithKnownEntries_ProducesHeaderRow()
    {
        var entry = MakeEntry("Web", "Site A", "https://contoso.sharepoint.com/sites/A",
            true, "alice@contoso.com", "i:0#.f|membership|alice@contoso.com",
            "Contribute", "Direct Permissions", "User");

        var svc = new CsvExportService();
        var csv = svc.BuildCsv(new[] { entry });

        Assert.Contains("Object", csv);
        Assert.Contains("Title", csv);
        Assert.Contains("URL", csv);
        Assert.Contains("HasUniquePermissions", csv);
        Assert.Contains("Users", csv);
        Assert.Contains("UserLogins", csv);
        Assert.Contains("Type", csv);
        Assert.Contains("Permissions", csv);
        Assert.Contains("GrantedThrough", csv);
    }

    [Fact]
    public void BuildCsv_WithEmptyList_ReturnsHeaderOnly()
    {
        var svc = new CsvExportService();
        var csv = svc.BuildCsv(Array.Empty<PermissionEntry>());

        // Should have exactly one line (header) or header + empty body
        Assert.NotEmpty(csv);
        Assert.Contains("Object", csv);
    }

    [Fact]
    public void BuildCsv_WithResolvedTarget_IncludesTargetColumns()
    {
        var entry = new PermissionEntry(
            ObjectType: "Site",
            Title: "HR",
            Url: "https://contoso.sharepoint.com/sites/HR",
            HasUniquePermissions: true,
            Users: "Limited Access System Group For List b20e3b22-2b09-4c99-9ba4-37b42f3a12dc",
            UserLogins: "Limited Access System Group For List b20e3b22-2b09-4c99-9ba4-37b42f3a12dc",
            PermissionLevels: "Limited Access: Edit",
            GrantedThrough: "SharePoint Group: Limited Access System Group For List b20e3b22-2b09-4c99-9ba4-37b42f3a12dc",
            PrincipalType: "SharePointGroup",
            TargetUrl: "https://contoso.sharepoint.com/sites/HR/Lists/Payroll",
            TargetLabel: "Payroll");

        var svc = new CsvExportService();
        var csv = svc.BuildCsv(new[] { entry });

        Assert.Contains("TargetLabel", csv);
        Assert.Contains("TargetUrl", csv);
        Assert.Contains("Payroll", csv);
        Assert.Contains("https://contoso.sharepoint.com/sites/HR/Lists/Payroll", csv);
    }

    [Fact]
    public void BuildCsv_WithSharingLink_IncludesLinkType()
    {
        var entry = new PermissionEntry(
            ObjectType: "Folder", Title: "Reports", Url: "https://contoso.sharepoint.com/sites/HR/Docs",
            HasUniquePermissions: true,
            Users: "SharingLinks.e686221e-d1cb-43c5-8c68-04aa7f90f329.OrganizationEdit.64c27910-66ea-421d-b0f0-8f0f72dcfaf6",
            UserLogins: "SharingLinks.e686221e-d1cb-43c5-8c68-04aa7f90f329.OrganizationEdit.64c27910-66ea-421d-b0f0-8f0f72dcfaf6",
            PermissionLevels: "Contribute",
            GrantedThrough: "SharePoint Group: SharingLinks.e686221e-d1cb-43c5-8c68-04aa7f90f329.OrganizationEdit.64c27910-66ea-421d-b0f0-8f0f72dcfaf6",
            PrincipalType: "SharePointGroup",
            TargetUrl: "https://contoso.sharepoint.com/sites/HR/Docs/Q4.xlsx",
            TargetLabel: "Q4.xlsx",
            SharingLinkType: "OrganizationEdit");

        var svc = new CsvExportService();
        var csv = svc.BuildCsv(new[] { entry });

        Assert.Contains("SharingLinkType", csv);
        Assert.Contains("OrganizationEdit", csv);
        Assert.Contains("Q4.xlsx", csv);
    }

    [Fact]
    public void BuildCsv_WithDuplicateUserPermissionGrantedThrough_MergesLocations()
    {
        // PERM-05 Merge-PermissionRows: two entries with same Users+PermissionLevels+GrantedThrough
        // but different URLs must be merged into one row with URLs pipe-joined.
        var entryA = MakeEntry("Web", "Site A", "https://contoso.sharepoint.com/sites/A",
            true, "alice@contoso.com", "i:0#.f|membership|alice@contoso.com",
            "Contribute", "Direct Permissions", "User");
        var entryB = MakeEntry("Web", "Site B", "https://contoso.sharepoint.com/sites/B",
            true, "alice@contoso.com", "i:0#.f|membership|alice@contoso.com",
            "Contribute", "Direct Permissions", "User");

        var svc = new CsvExportService();
        var csv = svc.BuildCsv(new[] { entryA, entryB });

        // Merged row must contain both URLs separated by " | "
        Assert.Contains("sites/A", csv);
        Assert.Contains("sites/B", csv);
        Assert.Contains("|", csv);
    }
}
