using CashLineERP.Application.Documents;
using CashLineERP.Application.Parties;
using CashLineERP.Contracts.Documents;
using CashLineERP.Contracts.Parties;
using CashLineERP.Infrastructure.Persistence.Repositories;
using CashLineERP.SharedKernel.Documents;

namespace CashLineERP.Api.Tests;

public sealed class DocumentStorageLifecycleServiceQaTests
{
    [Fact]
    public void Document_Storage_Can_Create_Archive_And_Supersede_Attachments()
    {
        using var dbContext = QaDbContextFactory.CreateContext();

        var documentStorageService = new DocumentStorageService(new DocumentStorageRepository(dbContext));

        var createdDocument = documentStorageService.CreateDocument(3, new CreateDocumentAttachmentRequest(
            ModuleCode: "SALES",
            EntityName: "DISPATCH_ORDER",
            EntityId: 1,
            DocumentType: "POD_IMAGE",
            AttachmentCategoryCode: DocumentAttachmentCategoryCode.DeliveryEvidence,
            FileName: "pod-photo-001.jpg",
            StorageReference: "dispatch/1/pod-photo-001.jpg",
            StorageProviderCode: DocumentStorageProviderCode.ManagedStorage,
            ContentType: "image/jpeg",
            FileSizeBytes: 8192,
            ChecksumText: "sha256:pod-001",
            RetentionUntilUtc: new DateTime(2027, 4, 5, 0, 0, 0, DateTimeKind.Utc)));

        Assert.Equal("ACTIVE", createdDocument.LifecycleStatusCode);
        Assert.Equal(1, createdDocument.VersionNumber);

        var archivedDocument = documentStorageService.ArchiveDocument(createdDocument.DocumentLinkId, 4, new ArchiveDocumentAttachmentRequest(
            ReasonText: "Retention exception archive"));

        Assert.Equal("ARCHIVED", archivedDocument.LifecycleStatusCode);
        Assert.Equal(4L, archivedDocument.ArchivedByUserId);
        Assert.NotNull(archivedDocument.ArchivedAtUtc);

        var replacementSeed = documentStorageService.CreateDocument(3, new CreateDocumentAttachmentRequest(
            ModuleCode: "PARTY",
            EntityName: "BUSINESS_PARTY",
            EntityId: 1,
            DocumentType: "VAT_CERTIFICATE",
            AttachmentCategoryCode: DocumentAttachmentCategoryCode.Compliance,
            FileName: "vat-certificate-v1.pdf",
            StorageReference: "party/1/vat-certificate-v1.pdf",
            StorageProviderCode: DocumentStorageProviderCode.ManagedStorage,
            ContentType: "application/pdf",
            FileSizeBytes: 2048,
            ChecksumText: "sha256:vat-v1",
            RetentionUntilUtc: null));

        var supersededDocument = documentStorageService.SupersedeDocument(replacementSeed.DocumentLinkId, 4, new SupersedeDocumentAttachmentRequest(
            FileName: "vat-certificate-v2.pdf",
            StorageReference: "party/1/vat-certificate-v2.pdf",
            StorageProviderCode: DocumentStorageProviderCode.ManagedStorage,
            ContentType: "application/pdf",
            FileSizeBytes: 3072,
            ChecksumText: "sha256:vat-v2",
            RetentionUntilUtc: null,
            ReasonText: "Updated registration document"));

        Assert.Equal(2, supersededDocument.VersionNumber);
        Assert.Equal("ACTIVE", supersededDocument.LifecycleStatusCode);

        var originalDocument = documentStorageService.GetDocument(replacementSeed.DocumentLinkId);
        Assert.NotNull(originalDocument);
        Assert.Equal("SUPERSEDED", originalDocument!.LifecycleStatusCode);
        Assert.Equal(supersededDocument.DocumentLinkId, originalDocument.SupersededByDocumentLinkId);
    }

    [Fact]
    public void Party_Compliance_Views_Only_Show_Active_Documents_After_Lifecycle_Changes()
    {
        using var dbContext = QaDbContextFactory.CreateContext();

        var partyService = new PartyOnboardingService(new BusinessPartyRepository(dbContext));
        var documentStorageService = new DocumentStorageService(new DocumentStorageRepository(dbContext));

        var originalDocument = partyService.RecordComplianceDocument(3, 1, new RecordBusinessPartyComplianceDocumentRequest(
            DocumentType: "commercial_register",
            FileName: "commercial-register-v1.pdf",
            StorageReference: "party/1/commercial-register-v1.pdf",
            ContentType: "application/pdf",
            FileSizeBytes: 4096));

        var replacementDocument = documentStorageService.SupersedeDocument(originalDocument.DocumentLinkId, 4, new SupersedeDocumentAttachmentRequest(
            FileName: "commercial-register-v2.pdf",
            StorageReference: "party/1/commercial-register-v2.pdf",
            StorageProviderCode: DocumentStorageProviderCode.ManagedStorage,
            ContentType: "application/pdf",
            FileSizeBytes: 5120,
            ChecksumText: "sha256:cr-v2",
            RetentionUntilUtc: null,
            ReasonText: "Uploaded renewed commercial register"));

        var activeDocuments = partyService.GetComplianceDocuments(1);
        var activeDocument = Assert.Single(activeDocuments, document => document.DocumentType == "COMMERCIAL_REGISTER");
        Assert.Equal(replacementDocument.DocumentLinkId, activeDocument.DocumentLinkId);
        Assert.Equal("commercial-register-v2.pdf", activeDocument.FileName);

        documentStorageService.ArchiveDocument(replacementDocument.DocumentLinkId, 4, new ArchiveDocumentAttachmentRequest(
            ReasonText: "Archived after case closure"));

        var documentsAfterArchive = partyService.GetComplianceDocuments(1);
        Assert.DoesNotContain(documentsAfterArchive, document => document.DocumentType == "COMMERCIAL_REGISTER");
    }
}
