using Microsoft.EntityFrameworkCore;
using Models.Interfaces;
using Domain.Entities;
using Models.Models;

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

        public async Task<EDeliveryNote?> GetByIdAsync(int id)
        {
            var entity = await _context.PhSDeliveryNotes
                .Include(x => x.PhSDeliveryNoteDetails)
                .AsNoTracking()
                .FirstOrDefaultAsync(x => x.Id == id);

            return entity == null ? null : MapDeliveryNote(entity);
        }

        public async Task<EDeliveryNote?> GetByDeliveryNoteNumberAsync(string deliveryNoteNumber)
        {
            var entity = await _context.PhSDeliveryNotes
                .Include(x => x.PhSDeliveryNoteDetails)
                .AsNoTracking()
                .FirstOrDefaultAsync(x => x.Deliverynotenumber == deliveryNoteNumber);

            return entity == null ? null : MapDeliveryNote(entity);
        }

        public async Task<IEnumerable<EDeliveryNote>> GetByQuoteIdAsync(int quoteId)
        {
            var entities = await _context.PhSDeliveryNotes
                .Include(x => x.PhSDeliveryNoteDetails)
                .AsNoTracking()
                .Where(x => x.QuoteId == quoteId)
                .OrderByDescending(x => x.Issuedate)
                .ThenByDescending(x => x.Id)
                .ToListAsync();

            return entities.Select(MapDeliveryNote);
        }

        private static EDeliveryNote MapDeliveryNote(PhSDeliveryNote source)
        {
            return new EDeliveryNote
            {
                Id = source.Id,
                DeliveryNoteNumber = source.Deliverynotenumber,
                QuoteId = source.QuoteId,
                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,
                PhSDeliveryNoteDetails = source.PhSDeliveryNoteDetails
                    .OrderBy(d => d.LineNumber)
                    .ThenBy(d => d.Id)
                    .Select(MapDeliveryNoteDetail)
                    .ToList()
            };
        }

        private static EDeliveryNoteDetail MapDeliveryNoteDetail(PhSDeliveryNoteDetail source)
        {
            return new EDeliveryNoteDetail
            {
                Id = source.Id,
                DeliverynoteId = source.DeliverynoteId,
                LineNumber = source.LineNumber,
                OriginType = source.OriginType,
                OriginId = source.OriginId,
                QuoteDetailId = source.QuoteDetailId,
                Description = source.Description,
                Quantity = source.Quantity,
                Notes = source.Notes,
                Createdat = source.Createdat,
                Modifiedat = source.Modifiedat
            };
        }
    }
}