package api

// Wire shapes for /api/library/sync upserts. The sqlc-generated row
// structs (dbq.Artist, dbq.Album, dbq.Track, dbq.Playlist) have no
// JSON tags (sqlc.yaml: emit_json_tags=false), so a raw json.Marshal
// of them produces PascalCase field names that the Flutter sync
// controller (which reads snake_case keys) can't parse.
//
// These view structs add the JSON tag layer + flatten pgtype.UUID and
// pgtype.Timestamptz / Date into strings, mirroring the pattern
// playlistRowView already established for /api/playlists.
//
// Field names match flutter_client/lib/cache/sync_controller.dart's
// _*FromJson helpers exactly. Adding a field server-side requires a
// matching read in the Flutter helper or it'll be silently dropped.

import (
	"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
	syncpkg "git.fabledsword.com/bvandeusen/minstrel/internal/sync"
)

type artistSyncView struct {
	ID               string  `json:"id"`
	Name             string  `json:"name"`
	SortName         string  `json:"sort_name"`
	Mbid             *string `json:"mbid"`
	ArtistThumbPath  *string `json:"artist_thumb_path"`
	ArtistFanartPath *string `json:"artist_fanart_path"`
}

func toArtistSyncView(a dbq.Artist) artistSyncView {
	return artistSyncView{
		ID:               syncpkg.FormatUUID(a.ID),
		Name:             a.Name,
		SortName:         a.SortName,
		Mbid:             a.Mbid,
		ArtistThumbPath:  a.ArtistThumbPath,
		ArtistFanartPath: a.ArtistFanartPath,
	}
}

type albumSyncView struct {
	ID           string  `json:"id"`
	ArtistID     string  `json:"artist_id"`
	Title        string  `json:"title"`
	SortTitle    string  `json:"sort_title"`
	ReleaseDate  *string `json:"release_date"`
	CoverArtPath *string `json:"cover_art_path"`
	Mbid         *string `json:"mbid"`
}

func toAlbumSyncView(a dbq.Album) albumSyncView {
	var releaseDate *string
	if a.ReleaseDate.Valid {
		s := a.ReleaseDate.Time.Format("2006-01-02")
		releaseDate = &s
	}
	return albumSyncView{
		ID:           syncpkg.FormatUUID(a.ID),
		ArtistID:     syncpkg.FormatUUID(a.ArtistID),
		Title:        a.Title,
		SortTitle:    a.SortTitle,
		ReleaseDate:  releaseDate,
		CoverArtPath: a.CoverArtPath,
		Mbid:         a.Mbid,
	}
}

type trackSyncView struct {
	ID          string  `json:"id"`
	AlbumID     string  `json:"album_id"`
	ArtistID    string  `json:"artist_id"`
	Title       string  `json:"title"`
	DurationMs  int32   `json:"duration_ms"`
	TrackNumber *int32  `json:"track_number"`
	DiscNumber  *int32  `json:"disc_number"`
	FilePath    string  `json:"file_path"`
	FileFormat  string  `json:"file_format"`
	Genre       *string `json:"genre"`
}

func toTrackSyncView(t dbq.Track) trackSyncView {
	return trackSyncView{
		ID:          syncpkg.FormatUUID(t.ID),
		AlbumID:     syncpkg.FormatUUID(t.AlbumID),
		ArtistID:    syncpkg.FormatUUID(t.ArtistID),
		Title:       t.Title,
		DurationMs:  t.DurationMs,
		TrackNumber: t.TrackNumber,
		DiscNumber:  t.DiscNumber,
		FilePath:    t.FilePath,
		FileFormat:  t.FileFormat,
		Genre:       t.Genre,
	}
}

type playlistSyncView struct {
	ID            string  `json:"id"`
	UserID        string  `json:"user_id"`
	Name          string  `json:"name"`
	Description   string  `json:"description"`
	IsPublic      bool    `json:"is_public"`
	CoverPath     *string `json:"cover_path"`
	TrackCount    int32   `json:"track_count"`
	DurationSec   int32   `json:"duration_sec"`
	SystemVariant *string `json:"system_variant"`
}

func toPlaylistSyncView(p dbq.Playlist) playlistSyncView {
	return playlistSyncView{
		ID:            syncpkg.FormatUUID(p.ID),
		UserID:        syncpkg.FormatUUID(p.UserID),
		Name:          p.Name,
		Description:   p.Description,
		IsPublic:      p.IsPublic,
		CoverPath:     p.CoverPath,
		TrackCount:    p.TrackCount,
		DurationSec:   p.DurationSec,
		SystemVariant: p.SystemVariant,
	}
}
