using ErsatzTV.Core.Domain;
using Microsoft.EntityFrameworkCore;

namespace ErsatzTV.Application.ProgramSchedules;

internal static class ProgramScheduleItemQueryExtensions
{
    /// <summary>
    ///     The single source of truth for the navigation graph a <see cref="ProgramScheduleItem" /> needs before
    ///     it can be projected via <see cref="Mapper.ProjectToViewModel" />. The mapper dereferences the
    ///     <c>Watermark</c> / <c>GraphicsElement</c> navs of each join row without a null guard, so any handler
    ///     that projects freshly-persisted items MUST reload through this include chain (see #229 — the write
    ///     path used to project the tracked-but-unloaded graph and threw a NullReferenceException, surfacing as a
    ///     500 on PUT/POST whenever an item carried a watermark or graphics element).
    /// </summary>
    public static IQueryable<ProgramScheduleItem> IncludeScheduleItemDetails(this IQueryable<ProgramScheduleItem> query) =>
        query
            .Include(i => i.Collection)
            .Include(i => i.MultiCollection)
            .Include(i => i.SmartCollection)
            .Include(i => i.RerunCollection)
            .Include(i => i.Playlist)
            .Include(i => i.MediaItem)
            .ThenInclude(i => (i as Movie).MovieMetadata)
            .ThenInclude(mm => mm.Artwork)
            .Include(i => i.MediaItem)
            .ThenInclude(i => (i as Season).SeasonMetadata)
            .ThenInclude(sm => sm.Artwork)
            .Include(i => i.MediaItem)
            .ThenInclude(i => (i as Season).Show)
            .ThenInclude(s => s.ShowMetadata)
            .ThenInclude(sm => sm.Artwork)
            .Include(i => i.MediaItem)
            .ThenInclude(i => (i as Show).ShowMetadata)
            .ThenInclude(sm => sm.Artwork)
            .Include(i => i.MediaItem)
            .ThenInclude(i => (i as Artist).ArtistMetadata)
            .ThenInclude(am => am.Artwork)
            .Include(i => i.PreRollFiller)
            .Include(i => i.MidRollFiller)
            .Include(i => i.PostRollFiller)
            .Include(i => i.TailFiller)
            .Include(i => i.FallbackFiller)
            .Include(i => i.ProgramScheduleItemWatermarks)
            .ThenInclude(i => i.Watermark)
            .Include(i => i.ProgramScheduleItemGraphicsElements)
            .ThenInclude(i => i.GraphicsElement);
}
