using PowderCoating.Core.Entities;

namespace PowderCoating.Core.Interfaces.Repositories;

/// <summary>
/// Typed repository for <see cref="JobItemCoat"/> that adds ThenInclude-based load methods the
/// generic <see cref="IRepository{T}"/> cannot express.  Used by DashboardController for powder
/// order marking, powder receipt, and custom powder inventory creation.
/// </summary>
public interface IJobItemCoatRepository : IRepository<JobItemCoat>
{
    /// <summary>
    /// Loads a coat with the full vendor + job chain needed by the <c>MarkPowderOrdered</c> action:
    /// <c>JobItem → Job → Customer</c>, <c>InventoryItem → PrimaryVendor</c>, and direct
    /// <c>Vendor</c>.  Returns <see langword="null"/> if not found.
    /// </summary>
    Task<JobItemCoat?> LoadForOrderMarkingAsync(int id);

    /// <summary>
    /// Loads a coat with only <c>InventoryItem</c> included — used by <c>ReceivePowder</c> for
    /// the initial stock update.  Returns <see langword="null"/> if not found.
    /// </summary>
    Task<JobItemCoat?> LoadWithInventoryAsync(int id);

    /// <summary>
    /// Loads a coat with <c>JobItem → Job</c> included — used by <c>ReceivePowder</c> to verify
    /// company ownership when the initial load did not include the job chain.  EF Core identity-map
    /// fixup propagates <c>JobItem</c> back to any previously tracked instance of the same coat.
    /// Returns <see langword="null"/> if not found.
    /// </summary>
    Task<JobItemCoat?> LoadWithJobChainAsync(int id);

    /// <summary>
    /// Returns all non-deleted coats that have no linked inventory item and belong to
    /// <paramref name="companyId"/>, excluding <paramref name="excludeCoatId"/>.  Used by
    /// <c>AddCustomPowderToInventory</c> to link sibling coats to the newly created item.
    /// Entities are tracked so that <c>InventoryItemId</c> mutations are saved via UnitOfWork.
    /// </summary>
    Task<List<JobItemCoat>> GetCandidateCoatsForLinkingAsync(int excludeCoatId, int companyId);
}
