using Microsoft.EntityFrameworkCore;
using PowderCoating.Core.Entities;
using PowderCoating.Core.Interfaces.Repositories;
using PowderCoating.Infrastructure.Data;

namespace PowderCoating.Infrastructure.Repositories;

/// <summary>
/// Typed repository for <see cref="JobItemCoat"/> that adds ThenInclude-based load methods the
/// generic <see cref="Repository{T}"/> cannot express.
/// </summary>
public class JobItemCoatRepository : Repository<JobItemCoat>, IJobItemCoatRepository
{
    public JobItemCoatRepository(ApplicationDbContext context) : base(context) { }

    /// <inheritdoc/>
    public async Task<JobItemCoat?> LoadForOrderMarkingAsync(int id)
    {
        return await _context.JobItemCoats
            .Include(c => c.JobItem).ThenInclude(i => i.Job).ThenInclude(j => j.Customer)
            .Include(c => c.Vendor)
            .Include(c => c.InventoryItem).ThenInclude(i => i!.PrimaryVendor)
            .FirstOrDefaultAsync(c => c.Id == id);
    }

    /// <inheritdoc/>
    public async Task<JobItemCoat?> LoadWithInventoryAsync(int id)
    {
        return await _context.JobItemCoats
            .Include(c => c.InventoryItem)
            .FirstOrDefaultAsync(c => c.Id == id);
    }

    /// <inheritdoc/>
    public async Task<JobItemCoat?> LoadWithJobChainAsync(int id)
    {
        return await _context.JobItemCoats
            .Include(c => c.JobItem).ThenInclude(i => i.Job)
            .FirstOrDefaultAsync(c => c.Id == id);
    }

    /// <inheritdoc/>
    public async Task<List<JobItemCoat>> GetCandidateCoatsForLinkingAsync(int excludeCoatId, int companyId)
    {
        return await _context.JobItemCoats
            .Include(c => c.JobItem)
            .Where(c => c.Id != excludeCoatId
                     && c.InventoryItemId == null
                     && c.JobItem.CompanyId == companyId)
            .ToListAsync();
    }
}
