using CashLineERP.Contracts.Documents;

namespace CashLineERP.Application.Documents;

public sealed class DocumentStorageService : IDocumentStorageService
{
    private readonly IDocumentStorageRepository _repository;

    public DocumentStorageService(IDocumentStorageRepository repository)
    {
        _repository = repository;
    }

    public IReadOnlyCollection<DocumentAttachmentResponse> GetDocuments(
        string? moduleCode = null,
        string? entityName = null,
        long? entityId = null,
        string? lifecycleStatusCode = null,
        string? attachmentCategoryCode = null) =>
        _repository.GetDocuments(moduleCode, entityName, entityId, lifecycleStatusCode, attachmentCategoryCode)
            .Select(Map)
            .ToArray();

    public DocumentAttachmentResponse? GetDocument(long documentLinkId)
    {
        var document = _repository.GetDocument(documentLinkId);
        return document is null ? null : Map(document);
    }

    public DocumentAttachmentResponse CreateDocument(long actorUserId, CreateDocumentAttachmentRequest request) =>
        Map(_repository.CreateDocument(actorUserId, new CreateDocumentAttachmentCommand(
            request.ModuleCode,
            request.EntityName,
            request.EntityId,
            request.DocumentType,
            request.AttachmentCategoryCode,
            request.FileName,
            request.StorageReference,
            request.StorageProviderCode,
            request.ContentType,
            request.FileSizeBytes,
            request.ChecksumText,
            request.RetentionUntilUtc)));

    public DocumentAttachmentResponse ArchiveDocument(long documentLinkId, long actorUserId, ArchiveDocumentAttachmentRequest request) =>
        Map(_repository.ArchiveDocument(documentLinkId, actorUserId, request.ReasonText));

    public DocumentAttachmentResponse SupersedeDocument(long documentLinkId, long actorUserId, SupersedeDocumentAttachmentRequest request) =>
        Map(_repository.SupersedeDocument(documentLinkId, actorUserId, new SupersedeDocumentAttachmentCommand(
            request.FileName,
            request.StorageReference,
            request.StorageProviderCode,
            request.ContentType,
            request.FileSizeBytes,
            request.ChecksumText,
            request.RetentionUntilUtc,
            request.ReasonText)));

    private static DocumentAttachmentResponse Map(DocumentAttachmentDetailView document) =>
        new(
            document.DocumentLinkId,
            document.ModuleCode,
            document.EntityName,
            document.EntityId,
            document.DocumentType,
            document.AttachmentCategoryCode,
            document.FileName,
            document.StorageReference,
            document.StorageProviderCode,
            document.ContentType,
            document.FileSizeBytes,
            document.ChecksumText,
            document.LifecycleStatusCode,
            document.VersionNumber,
            document.SupersededByDocumentLinkId,
            document.RetentionUntilUtc,
            document.ArchivedAtUtc,
            document.ArchivedByUserId,
            document.LifecycleNotesText,
            document.UploadedAtUtc,
            document.UploadedByUserId);
}
