package artwork

import (
	"context"
	"fmt"
	"io"
	"time"

	"github.com/navidrome/navidrome/conf"
	"github.com/navidrome/navidrome/model"
)

type mediafileArtworkReader struct {
	cacheKey
	a         *artwork
	mediafile model.MediaFile
	album     model.Album
	lib       libraryView
}

func newMediafileArtworkReader(ctx context.Context, artwork *artwork, artID model.ArtworkID) (*mediafileArtworkReader, error) {
	mf, err := artwork.ds.MediaFile(ctx).Get(artID.ID)
	if err != nil {
		return nil, err
	}
	al, err := artwork.ds.Album(ctx).Get(mf.AlbumID)
	if err != nil {
		return nil, err
	}
	_, _, imagesUpdatedAt, err := loadAlbumFoldersPaths(ctx, artwork.ds, *al)
	if err != nil {
		return nil, err
	}
	lib, err := loadLibraryView(ctx, artwork.ds, mf.LibraryID)
	if err != nil {
		return nil, err
	}
	a := &mediafileArtworkReader{
		a:         artwork,
		mediafile: *mf,
		album:     *al,
		lib:       lib,
	}
	a.cacheKey.artID = artID
	a.cacheKey.lastUpdate = mf.UpdatedAt
	if al.UpdatedAt.After(a.cacheKey.lastUpdate) {
		a.cacheKey.lastUpdate = al.UpdatedAt
	}
	if imagesUpdatedAt != nil && imagesUpdatedAt.After(a.cacheKey.lastUpdate) {
		a.cacheKey.lastUpdate = *imagesUpdatedAt
	}
	return a, nil
}

func (a *mediafileArtworkReader) Key() string {
	return fmt.Sprintf(
		"%s.%t",
		a.cacheKey.Key(),
		conf.Server.EnableMediaFileCoverArt,
	)
}
func (a *mediafileArtworkReader) LastUpdated() time.Time {
	return a.lastUpdate
}

func (a *mediafileArtworkReader) Reader(ctx context.Context) (io.ReadCloser, string, error) {
	var ff []sourceFunc
	if a.mediafile.CoverArtID().Kind == model.KindMediaFileArtwork {
		ff = []sourceFunc{
			fromTag(ctx, a.lib.FS, a.mediafile.Path),
			fromFFmpegTag(ctx, a.a.ffmpeg, a.lib.Abs(a.mediafile.Path)),
		}
	}
	// For multi-disc albums, fall back to disc artwork first; for single-disc albums,
	// skip disc resolution (it would just fall through to album art anyway).
	if len(a.album.Discs) > 1 {
		ff = append(ff, fromAlbum(ctx, a.a, a.mediafile.DiscCoverArtID()))
	} else {
		ff = append(ff, fromAlbum(ctx, a.a, a.mediafile.AlbumCoverArtID()))
	}
	return selectImageReader(ctx, a.artID, ff...)
}
