using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Metadata;

namespace ErsatzTV.Core.Interfaces.Repositories;

public interface IMediaServerMusicVideoRepository<in TLibrary, TMusicVideo, TEtag> where TLibrary : Library
    where TMusicVideo : MusicVideo
    where TEtag : MediaServerItemEtag
{
    Task<List<TEtag>> GetExistingMusicVideos(TLibrary library);
    Task<Option<int>> FlagNormal(TLibrary library, TMusicVideo musicVideo);
    Task<Option<int>> FlagUnavailable(TLibrary library, TMusicVideo musicVideo);
    Task<List<int>> FlagFileNotFound(TLibrary library, List<string> musicVideoItemIds);

    // Unlike the movie/other-video seams, GetOrAdd takes the resolved Artist and LibraryFolder: a music video is
    // owned by an Artist (FK, not null) and ersatztv#488 requires the media file to carry its LibraryFolderId.
    //
    // `localPath` is the PATH-REPLACED local path and is the only path this seam may store or match on. The
    // `item` argument still carries the path the media server reported, which for any install with configured
    // path replacements is a DIFFERENT string — matching or storing that one would miss the row it is meant to
    // find and duplicate it under a server-side path (ersatztv#496).
    Task<Either<BaseError, MediaItemScanResult<TMusicVideo>>> GetOrAdd(
        TLibrary library,
        Artist artist,
        LibraryFolder libraryFolder,
        TMusicVideo item,
        string localPath,
        bool deepScan,
        CancellationToken cancellationToken);

    // ersatztv#496: music videos that predate per-item identity carry no TEtag row, so they are invisible to the
    // itemId diff above. They are reconciled by their local path until a scan adopts them.
    Task<List<string>> GetExistingLegacyMusicVideoPaths(TLibrary library);
    Task<List<int>> FlagFileNotFoundByPaths(TLibrary library, List<string> localPaths);

    Task<Unit> SetEtag(TMusicVideo musicVideo, string etag);
}
