using Domain.Constants;
using Domain.Dtos.Sales;
using Domain.Entities;
using Domain.Generics;
using Microsoft.EntityFrameworkCore;
using Models.Helpers;
using Models.Interfaces;
using Models.Models;

namespace Models.Repositories
{
    public class PhSSalesDocumentRepository(PhronCareOperationsHubContext context) : IPhSSalesDocumentRepository
    {
        private readonly PhronCareOperationsHubContext _context = context;

        public async Task<PagedResult<SalesDocumentSummaryDto>> SearchAsync(
            int? customerId,
            string? customerText,
            int? quoteId,
            int? documentType,
            int? status,
            DateTime? issueDateFrom,
            DateTime? issueDateTo,
            int page = 1,
            int pageSize = 50)
        {
            page = page <= 0 ? 1 : page;
            pageSize = pageSize <= 0 ? 50 : pageSize;

            var query = _context.PhSSalesDocuments
                .Include(x => x.Customer)
                .Include(x => x.BillToCustomer)
                .AsNoTracking()
                .AsQueryable();

            if (customerId.HasValue && customerId.Value > 0)
            {
                query = query.Where(x => x.CustomerId == customerId.Value || x.BillToCustomerId == customerId.Value);
            }

            if (!string.IsNullOrWhiteSpace(customerText))
            {
                var normalizedCustomerText = customerText.Trim();
                query = query.Where(x =>
                    (x.Customer.Name ?? string.Empty).Contains(normalizedCustomerText) ||
                    (x.BillToCustomer.Name ?? string.Empty).Contains(normalizedCustomerText));
            }

            if (quoteId.HasValue && quoteId.Value > 0)
            {
                query = query.Where(x => x.QuoteId == quoteId.Value);
            }

            if (documentType.HasValue && documentType.Value > 0)
            {
                query = query.Where(x => x.DocumentType == documentType.Value);
            }

            if (status.HasValue && status.Value > 0)
            {
                query = query.Where(x => x.Status == status.Value);
            }

            if (issueDateFrom.HasValue)
            {
                query = query.Where(x => x.IssueDate >= issueDateFrom.Value);
            }

            if (issueDateTo.HasValue)
            {
                query = query.Where(x => x.IssueDate <= issueDateTo.Value);
            }

            var totalItems = await query.CountAsync();

            var items = await query
                .OrderByDescending(x => x.IssueDate)
                .ThenByDescending(x => x.Id)
                .Skip((page - 1) * pageSize)
                .Take(pageSize)
                .Select(x => new SalesDocumentSummaryDto
                {
                    Id = x.Id,
                    InternalDocumentNumber = x.InternalDocumentNumber,
                    DocumentType = x.DocumentType,
                    Status = x.Status,
                    QuoteId = x.QuoteId,
                    CustomerId = x.CustomerId,
                    CustomerName = x.Customer.Name ?? string.Empty,
                    BillToCustomerId = x.BillToCustomerId,
                    BillToCustomerName = x.BillToCustomer.Name ?? string.Empty,
                    IssueDate = x.IssueDate,
                    Currency = x.Currency,
                    NetAmount = x.NetAmount,
                    TaxAmount = x.TaxAmount,
                    TotalAmount = x.TotalAmount,
                    PeriodFrom = x.PeriodFrom,
                    PeriodTo = x.PeriodTo,
                    Createdat = x.Createdat,
                    Modifiedat = x.Modifiedat
                })
                .ToListAsync();

            return new PagedResult<SalesDocumentSummaryDto>
            {
                Items = items,
                TotalItems = totalItems,
                Page = page,
                PageSize = pageSize
            };
        }

        public async Task<ESalesDocument> CreateAsync(ESalesDocument entity)
        {
            var mapped = EntityMapper.MapEntity<ESalesDocument, PhSSalesDocument>(entity);

            await _context.PhSSalesDocuments.AddAsync(mapped);
            await _context.SaveChangesAsync();

            return EntityMapper.MapEntity<PhSSalesDocument, ESalesDocument>(mapped);
        }


        public async Task<PagedResult<SalesDocumentDeliveryNoteCandidateDto>> SearchDeliveryNoteCandidatesAsync(
            int? customerId,
            string? customerText,
            string? deliveryNoteNumber,
            int? quoteId,
            DateTime? issueDateFrom,
            DateTime? issueDateTo,
            int page = 1,
            int pageSize = 50)
        {
            page = page <= 0 ? 1 : page;
            pageSize = pageSize <= 0 ? 50 : pageSize;

            var query = _context.PhSDeliveryNotes
                .Include(x => x.Customer)
                .Include(x => x.Quote)
                .Include(x => x.PhSDeliveryNoteDetails)
                    .ThenInclude(d => d.QuoteDetail)
                .AsNoTracking()
                .Where(x => x.Status == "Emitido" && x.SalesinvoiceId == null)
                .AsQueryable();

            if (customerId.HasValue && customerId.Value > 0)
                query = query.Where(x => x.CustomerId == customerId.Value);
            else if (!string.IsNullOrWhiteSpace(customerText))
                query = query.Where(x => (x.Customer.Name ?? string.Empty).Contains(customerText.Trim()));

            if (!string.IsNullOrWhiteSpace(deliveryNoteNumber))
                query = query.Where(x => x.Deliverynotenumber.Contains(deliveryNoteNumber.Trim()));

            if (quoteId.HasValue && quoteId.Value > 0)
                query = query.Where(x => x.QuoteId == quoteId.Value);

            if (issueDateFrom.HasValue)
                query = query.Where(x => x.Issuedate >= issueDateFrom.Value);

            if (issueDateTo.HasValue)
                query = query.Where(x => x.Issuedate <= issueDateTo.Value);

            var totalItems = await query.CountAsync();

            var items = await query
                .OrderByDescending(x => x.Issuedate)
                .ThenByDescending(x => x.Id)
                .Skip((page - 1) * pageSize)
                .Take(pageSize)
                .Select(x => new SalesDocumentDeliveryNoteCandidateDto
                {
                    Id = x.Id,
                    DeliveryNoteNumber = x.Deliverynotenumber,
                    QuoteId = x.QuoteId,
                    QuoteNumber = x.Quote != null ? x.Quote.Quotenumber : null,
                    IssueDate = x.Issuedate,
                    CustomerId = x.CustomerId,
                    CustomerName = x.Customer.Name ?? string.Empty,
                    Status = x.Status,
                    ItemCount = x.PhSDeliveryNoteDetails.Count,
                    ApprovedAmount = x.PhSDeliveryNoteDetails.Sum(d => d.QuoteDetail != null
                        ? (d.QuoteDetail.Approvedamount ?? ((d.QuoteDetail.Approvedunitprice ?? d.QuoteDetail.Unitprice) * d.Quantity))
                        : 0),
                    ExtraInfoJson = x.ExtrainfoJson
                })
                .ToListAsync();

            return new PagedResult<SalesDocumentDeliveryNoteCandidateDto>
            {
                Items = items,
                TotalItems = totalItems,
                Page = page,
                PageSize = pageSize
            };
        }

        public async Task<List<DeliveryNoteDto>> GetDeliveryNotesForSalesDocumentAsync(IReadOnlyCollection<int> deliveryNoteIds)
        {
            var ids = deliveryNoteIds.Distinct().ToList();

            var entities = await _context.PhSDeliveryNotes
                .Include(x => x.Customer)
                .Include(x => x.Quote)
                .Include(x => x.PhSDeliveryNoteDetails)
                    .ThenInclude(d => d.QuoteDetail)
                .AsNoTracking()
                .Where(x => ids.Contains(x.Id))
                .OrderBy(x => x.Issuedate)
                .ThenBy(x => x.Id)
                .ToListAsync();

            return entities.Select(MapDeliveryNoteDto).ToList();
        }

        public async Task<ESalesDocument> CreateFromDeliveryNotesAsync(ESalesDocument entity, IReadOnlyCollection<int> deliveryNoteIds)
        {
            await using var transaction = await _context.Database.BeginTransactionAsync();

            var mapped = EntityMapper.MapEntity<ESalesDocument, PhSSalesDocument>(entity);
            await _context.PhSSalesDocuments.AddAsync(mapped);
            await _context.SaveChangesAsync();

            var ids = deliveryNoteIds.Distinct().ToList();
            var deliveryNotes = await _context.PhSDeliveryNotes
                .Where(x => ids.Contains(x.Id))
                .ToListAsync();

            foreach (var deliveryNote in deliveryNotes)
            {
                deliveryNote.SalesinvoiceId = mapped.Id;
                deliveryNote.Modifiedat = DateTime.Now;
            }

            await _context.SaveChangesAsync();
            await transaction.CommitAsync();

            return EntityMapper.MapEntity<PhSSalesDocument, ESalesDocument>(mapped);
        }

        public async Task<ESalesDocument> CreateFromDeliveryNoteItemsAsync(ESalesDocument entity)
        {
            await using var transaction = await _context.Database.BeginTransactionAsync();

            var mapped = EntityMapper.MapEntity<ESalesDocument, PhSSalesDocument>(entity);
            var detailCoverages = mapped.PhSSalesDocumentDetails
                .SelectMany(detail => detail.PhSSalesDocumentCoverages.Select(coverage => new
                {
                    Detail = detail,
                    Coverage = coverage
                }))
                .ToList();

            foreach (var detail in mapped.PhSSalesDocumentDetails)
                detail.PhSSalesDocumentCoverages.Clear();

            await _context.PhSSalesDocuments.AddAsync(mapped);
            await _context.SaveChangesAsync();

            foreach (var item in detailCoverages)
            {
                item.Coverage.SalesdocumentId = mapped.Id;
                item.Coverage.SalesdocumentdetailId = item.Detail.Id;
                await _context.PhSSalesDocumentCoverages.AddAsync(item.Coverage);
            }

            await _context.SaveChangesAsync();
            await transaction.CommitAsync();

            return EntityMapper.MapEntity<PhSSalesDocument, ESalesDocument>(mapped);
        }

        public async Task<List<SalesDocumentDeliveryNoteItemCandidateDto>> GetDeliveryNoteItemCandidatesForSalesDocumentAsync(IReadOnlyCollection<int> deliveryNoteIds)
        {
            var ids = deliveryNoteIds
                .Where(x => x > 0)
                .Distinct()
                .ToList();

            if (ids.Count == 0)
                return new List<SalesDocumentDeliveryNoteItemCandidateDto>();

            var deliveryNoteOrigin = SalesDocumentOriginType.DeliveryNote.ToStorageCode();
            var cancelledStatus = (int)SalesDocumentStatus.Cancelled;

            var details = await _context.PhSDeliveryNoteDetails
                .Include(x => x.Deliverynote)
                    .ThenInclude(x => x.Customer)
                .Include(x => x.Deliverynote)
                    .ThenInclude(x => x.Quote)
                .Include(x => x.QuoteDetail)
                .AsNoTracking()
                .Where(x => ids.Contains(x.DeliverynoteId) && x.Deliverynote.Status == "Emitido")
                .OrderBy(x => x.Deliverynote.Issuedate)
                .ThenBy(x => x.Deliverynote.Id)
                .ThenBy(x => x.LineNumber)
                .ThenBy(x => x.Id)
                .ToListAsync();

            var detailIds = details.Select(x => x.Id).ToList();

            var billedByDeliveryNoteDetail = await _context.PhSSalesDocumentDetails
                .AsNoTracking()
                .Where(x =>
                    x.OriginType == deliveryNoteOrigin &&
                    x.OriginId.HasValue &&
                    detailIds.Contains(x.OriginId.Value) &&
                    x.Salesdocument.Status != cancelledStatus)
                .GroupBy(x => x.OriginId!.Value)
                .Select(x => new
                {
                    DeliveryNoteDetailId = x.Key,
                    Quantity = x.Sum(d => d.Quantity)
                })
                .ToDictionaryAsync(x => x.DeliveryNoteDetailId, x => x.Quantity);

            return details
                .Select(x =>
                {
                    var approvedUnitPrice = x.QuoteDetail?.Approvedunitprice ?? x.QuoteDetail?.Unitprice ?? 0;
                    var approvedAmount = x.QuoteDetail?.Approvedamount ?? (approvedUnitPrice * x.Quantity);
                    var lineLevelBilledQuantity = billedByDeliveryNoteDetail.TryGetValue(x.Id, out var billedQuantity)
                        ? billedQuantity
                        : 0;
                    var legacyFullBilledQuantity = x.Deliverynote.SalesinvoiceId.HasValue && lineLevelBilledQuantity == 0
                        ? x.Quantity
                        : 0;
                    var alreadyBilledQuantity = lineLevelBilledQuantity + legacyFullBilledQuantity;
                    var pendingQuantity = Math.Max(0, x.Quantity - alreadyBilledQuantity);
                    var selectedAmount = approvedUnitPrice * pendingQuantity;

                    return new SalesDocumentDeliveryNoteItemCandidateDto
                    {
                        DeliveryNoteId = x.DeliverynoteId,
                        DeliveryNoteNumber = x.Deliverynote.Deliverynotenumber,
                        DeliveryNoteIssueDate = x.Deliverynote.Issuedate,
                        DeliveryNoteDetailId = x.Id,
                        LineNumber = x.LineNumber,
                        QuoteId = x.Deliverynote.QuoteId,
                        QuoteNumber = x.Deliverynote.Quote?.Quotenumber,
                        QuoteDetailId = x.QuoteDetailId,
                        ProductId = x.QuoteDetail?.ProductId,
                        CustomerId = x.Deliverynote.CustomerId,
                        CustomerName = x.Deliverynote.Customer.Name ?? string.Empty,
                        Description = x.Description ?? string.Empty,
                        DeliveredQuantity = x.Quantity,
                        AlreadyBilledQuantity = alreadyBilledQuantity,
                        PendingQuantity = pendingQuantity,
                        SelectedQuantity = pendingQuantity,
                        ApprovedUnitPrice = approvedUnitPrice,
                        ApprovedAmount = approvedAmount,
                        SelectedAmount = selectedAmount,
                        DeliveryNoteExtraInfoJson = x.Deliverynote.ExtrainfoJson
                    };
                })
                .Where(x => x.PendingQuantity > 0)
                .ToList();
        }

        public async Task<List<SalesDocumentDeliveryNoteItemCandidateDto>> GetDeliveryNoteItemCandidatesByDetailIdsForSalesDocumentAsync(IReadOnlyCollection<int> deliveryNoteDetailIds)
        {
            var ids = deliveryNoteDetailIds
                .Where(x => x > 0)
                .Distinct()
                .ToList();

            if (ids.Count == 0)
                return new List<SalesDocumentDeliveryNoteItemCandidateDto>();

            var deliveryNoteOrigin = SalesDocumentOriginType.DeliveryNote.ToStorageCode();
            var cancelledStatus = (int)SalesDocumentStatus.Cancelled;

            var details = await _context.PhSDeliveryNoteDetails
                .Include(x => x.Deliverynote)
                    .ThenInclude(x => x.Customer)
                .Include(x => x.Deliverynote)
                    .ThenInclude(x => x.Quote)
                .Include(x => x.QuoteDetail)
                .AsNoTracking()
                .Where(x => ids.Contains(x.Id) && x.Deliverynote.Status == "Emitido")
                .OrderBy(x => x.Deliverynote.Issuedate)
                .ThenBy(x => x.Deliverynote.Id)
                .ThenBy(x => x.LineNumber)
                .ThenBy(x => x.Id)
                .ToListAsync();

            var detailIds = details.Select(x => x.Id).ToList();

            var billedByDeliveryNoteDetail = await _context.PhSSalesDocumentDetails
                .AsNoTracking()
                .Where(x =>
                    x.OriginType == deliveryNoteOrigin &&
                    x.OriginId.HasValue &&
                    detailIds.Contains(x.OriginId.Value) &&
                    x.Salesdocument.Status != cancelledStatus)
                .GroupBy(x => x.OriginId!.Value)
                .Select(x => new
                {
                    DeliveryNoteDetailId = x.Key,
                    Quantity = x.Sum(d => d.Quantity)
                })
                .ToDictionaryAsync(x => x.DeliveryNoteDetailId, x => x.Quantity);

            return details
                .Select(x =>
                {
                    var approvedUnitPrice = x.QuoteDetail?.Approvedunitprice ?? x.QuoteDetail?.Unitprice ?? 0;
                    var approvedAmount = x.QuoteDetail?.Approvedamount ?? (approvedUnitPrice * x.Quantity);
                    var lineLevelBilledQuantity = billedByDeliveryNoteDetail.TryGetValue(x.Id, out var billedQuantity)
                        ? billedQuantity
                        : 0;
                    var legacyFullBilledQuantity = x.Deliverynote.SalesinvoiceId.HasValue && lineLevelBilledQuantity == 0
                        ? x.Quantity
                        : 0;
                    var alreadyBilledQuantity = lineLevelBilledQuantity + legacyFullBilledQuantity;
                    var pendingQuantity = Math.Max(0, x.Quantity - alreadyBilledQuantity);
                    var selectedAmount = approvedUnitPrice * pendingQuantity;

                    return new SalesDocumentDeliveryNoteItemCandidateDto
                    {
                        DeliveryNoteId = x.DeliverynoteId,
                        DeliveryNoteNumber = x.Deliverynote.Deliverynotenumber,
                        DeliveryNoteIssueDate = x.Deliverynote.Issuedate,
                        DeliveryNoteDetailId = x.Id,
                        LineNumber = x.LineNumber,
                        QuoteId = x.Deliverynote.QuoteId,
                        QuoteNumber = x.Deliverynote.Quote?.Quotenumber,
                        QuoteDetailId = x.QuoteDetailId,
                        ProductId = x.QuoteDetail?.ProductId,
                        CustomerId = x.Deliverynote.CustomerId,
                        CustomerName = x.Deliverynote.Customer.Name ?? string.Empty,
                        Description = x.Description ?? string.Empty,
                        DeliveredQuantity = x.Quantity,
                        AlreadyBilledQuantity = alreadyBilledQuantity,
                        PendingQuantity = pendingQuantity,
                        SelectedQuantity = pendingQuantity,
                        ApprovedUnitPrice = approvedUnitPrice,
                        ApprovedAmount = approvedAmount,
                        SelectedAmount = selectedAmount,
                        DeliveryNoteExtraInfoJson = x.Deliverynote.ExtrainfoJson
                    };
                })
                .ToList();
        }

        private static DeliveryNoteDto MapDeliveryNoteDto(PhSDeliveryNote source)
        {
            return new DeliveryNoteDto
            {
                Id = source.Id,
                DeliveryNoteNumber = source.Deliverynotenumber,
                CustomerName = source.Customer?.Name ?? string.Empty,
                QuoteId = source.QuoteId,
                QuoteNumber = source.Quote?.Quotenumber,
                SalesInvoiceId = source.SalesinvoiceId,
                IssueDate = source.Issuedate,
                CustomerId = source.CustomerId,
                Status = source.Status,
                Observations = source.Observations,
                ExtraInfoJson = source.ExtrainfoJson,
                PrintCount = source.Printcount,
                CreatedAt = source.Createdat,
                ModifiedAt = source.Modifiedat,
                Items = source.PhSDeliveryNoteDetails
                    .OrderBy(d => d.LineNumber)
                    .ThenBy(d => d.Id)
                    .Select(d => new DeliveryNoteItemDto
                    {
                        Id = d.Id,
                        DeliverynoteId = d.DeliverynoteId,
                        LineNumber = d.LineNumber,
                        OriginType = d.OriginType,
                        OriginId = d.OriginId,
                        QuoteDetailId = d.QuoteDetailId,
                        Description = d.Description ?? string.Empty,
                        Quantity = d.Quantity,
                        ProductId = d.QuoteDetail?.ProductId,
                        ApprovedUnitPrice = d.QuoteDetail?.Approvedunitprice,
                        ApprovedAmount = d.QuoteDetail?.Approvedamount,
                        OriginalUnitPrice = d.QuoteDetail?.Unitprice,
                        Notes = d.Notes,
                        Createdat = d.Createdat,
                        Modifiedat = d.Modifiedat
                    })
                    .ToList()
            };
        }

        public async Task<SalesDocumentDto?> GetDtoByIdAsync(int id)
        {
            var entity = await _context.PhSSalesDocuments
                .Include(x => x.Customer)
                .Include(x => x.BillToCustomer)
                .Include(x => x.PhSSalesDocumentDetails)
                .Include(x => x.PhSSalesDocumentCoverages)
                .AsNoTracking()
                .FirstOrDefaultAsync(x => x.Id == id);

            if (entity == null)
                return null;

            return new SalesDocumentDto
            {
                Id = entity.Id,
                FormseriesId = entity.FormseriesId,
                InternalSequenceNumber = entity.InternalSequenceNumber,
                InternalDocumentNumber = entity.InternalDocumentNumber,
                DocumentType = entity.DocumentType,
                FiscalVoucherType = entity.FiscalVoucherType,
                FiscalVoucherLetter = entity.FiscalVoucherLetter,
                Status = entity.Status,
                QuoteId = entity.QuoteId,
                CustomerId = entity.CustomerId,
                CustomerName = entity.Customer?.Name ?? string.Empty,
                BillToCustomerId = entity.BillToCustomerId,
                BillToCustomerName = entity.BillToCustomer?.Name ?? string.Empty,
                IssueDate = entity.IssueDate,
                Currency = entity.Currency,
                ExchangeRate = entity.ExchangeRate,
                NetAmount = entity.NetAmount,
                TaxAmount = entity.TaxAmount,
                TotalAmount = entity.TotalAmount,
                AssociatedDocumentType = entity.AssociatedDocumentType,
                AssociatedDocumentNumber = entity.AssociatedDocumentNumber,
                AssociatedDocumentDate = entity.AssociatedDocumentDate,
                Observations = entity.Observations,
                ExtraInfoJson = entity.ExtraInfoJson,
                PeriodFrom = entity.PeriodFrom,
                PeriodTo = entity.PeriodTo,
                Createdat = entity.Createdat,
                Modifiedat = entity.Modifiedat,
                Details = entity.PhSSalesDocumentDetails.Select(x => new SalesDocumentDetailDto
                {
                    Id = x.Id,
                    SalesDocumentId = x.SalesdocumentId,
                    LineNumber = x.LineNumber,
                    OriginType = x.OriginType,
                    OriginId = x.OriginId,
                    QuoteDetailId = x.QuoteDetailId,
                    ProductId = x.ProductId,
                    Description = x.Description,
                    Quantity = x.Quantity,
                    AuthorizedUnitPrice = x.AuthorizedUnitPrice,
                    AuthorizedAmount = x.AuthorizedAmount,
                    BilledPercentage = x.BilledPercentage,
                    UnitPrice = x.UnitPrice,
                    NetAmount = x.NetAmount,
                    TaxAmount = x.TaxAmount,
                    TotalAmount = x.TotalAmount,
                    OriginSnapshotJson = x.OriginSnapshotJson,
                    Createdat = x.Createdat,
                    Modifiedat = x.Modifiedat
                }).ToList(),
                Coverage = entity.PhSSalesDocumentCoverages.Select(x => new SalesDocumentCoverageDto
                {
                    Id = x.Id,
                    SalesDocumentId = x.SalesdocumentId,
                    SalesDocumentDetailId = x.SalesdocumentdetailId,
                    QuoteId = x.QuoteId,
                    QuoteDetailId = x.QuoteDetailId,
                    CoverageType = x.CoverageType,
                    CoveragePercentage = x.CoveragePercentage,
                    CoverageAmount = x.CoverageAmount,
                    PeriodFrom = x.PeriodFrom,
                    PeriodTo = x.PeriodTo,
                    Notes = x.Notes,
                    Createdat = x.Createdat,
                    Modifiedat = x.Modifiedat
                }).ToList()
            };
        }

        public async Task<SalesDocumentDto?> UpdateDraftReviewAsync(int id, SalesDocumentDraftReviewDto review)
        {
            var entity = await _context.PhSSalesDocuments
                .FirstOrDefaultAsync(x => x.Id == id);

            if (entity == null)
                return null;

            if (entity.Status != (int)Domain.Constants.SalesDocumentStatus.Draft)
                throw new InvalidOperationException("Solo se pueden revisar Sales Documents en estado Draft.");

            entity.IssueDate = review.IssueDate;
            entity.AssociatedDocumentType = string.IsNullOrWhiteSpace(review.AssociatedDocumentType) ? null : review.AssociatedDocumentType.Trim();
            entity.AssociatedDocumentNumber = string.IsNullOrWhiteSpace(review.AssociatedDocumentNumber) ? null : review.AssociatedDocumentNumber.Trim();
            entity.AssociatedDocumentDate = review.AssociatedDocumentDate;
            entity.Observations = string.IsNullOrWhiteSpace(review.Observations) ? null : review.Observations.Trim();
            entity.PeriodFrom = review.PeriodFrom;
            entity.PeriodTo = review.PeriodTo;
            entity.Modifiedat = DateTime.Now;

            await _context.SaveChangesAsync();
            return await GetDtoByIdAsync(id);
        }

        public async Task<SalesDocumentDto?> ValidateDraftAsync(int id)
        {
            var entity = await _context.PhSSalesDocuments
                .Include(x => x.PhSSalesDocumentDetails)
                .FirstOrDefaultAsync(x => x.Id == id);

            if (entity == null)
                return null;

            if (entity.Status != (int)Domain.Constants.SalesDocumentStatus.Draft)
                throw new InvalidOperationException("Solo se pueden validar Sales Documents en estado Draft.");

            entity.Status = (int)Domain.Constants.SalesDocumentStatus.Validated;
            entity.Modifiedat = DateTime.Now;

            await _context.SaveChangesAsync();
            return await GetDtoByIdAsync(id);
        }
    }
}
