package ui

import (
	"bytes"
	"image"
	_ "image/jpeg"
	_ "image/png"
	"path/filepath"

	"github.com/MattiaPun/SubTUI/v2/internal/api"
	tea "github.com/charmbracelet/bubbletea"
	_ "golang.org/x/image/webp"
)

func attemptLoginCmd() tea.Cmd {
	return func() tea.Msg {
		if err := api.SaveConfig(filepath.Join(api.ConfigDir, "credentials.toml"), api.AppServerConfig, 0600); err != nil {
			return loginResultMsg{err: err}
		}

		err := api.SubsonicLoginCheck()
		return loginResultMsg{err: err}
	}
}

func searchCmd(query string, mode int, offset int) tea.Cmd {
	return func() tea.Msg {

		switch mode {
		case filterSongs:
			songs, err := api.SubsonicSearchSong(query, offset)
			if err != nil {
				return errMsg{err}
			}
			return songsResultMsg{songs}

		case filterAlbums:
			albums, err := api.SubsonicSearchAlbum(query, offset)
			if err != nil {
				return errMsg{err}
			}
			return albumsResultMsg{albums}

		case filterArtist:
			artists, err := api.SubsonicSearchArtist(query, offset)
			if err != nil {
				return errMsg{err}
			}
			return artistsResultMsg{artists}
		}

		return nil
	}
}

func getAlbumSongs(albumID string, shuffled bool) tea.Cmd {
	return func() tea.Msg {
		songs, err := api.SubsonicGetAlbum(albumID)
		if err != nil {
			return errMsg{err}
		}

		if shuffled {
			return shuffledSongsMsg{songs, false}
		} else {
			return songsResultMsg{songs}
		}
	}
}

func getAlbumList(searchType string, offset int) tea.Cmd {
	return func() tea.Msg {
		albums, err := api.SubsonicGetAlbumList(searchType, offset)
		if err != nil {
			return errMsg{err}
		}
		return albumsResultMsg{albums}
	}
}

func getArtistAlbums(artistID string) tea.Cmd {
	return func() tea.Msg {
		albums, err := api.SubsonicGetArtist(artistID)
		if err != nil {
			return errMsg{err}
		}
		return albumsResultMsg{albums}
	}
}

func getPlaylists() tea.Cmd {
	return func() tea.Msg {
		playlists, err := api.SubsonicGetPlaylists()
		if err != nil {
			return errMsg{err}
		}
		return playlistResultMsg{playlists}
	}
}

func getPlaylistSongs(id string, shuffled bool) tea.Cmd {
	return func() tea.Msg {
		songs, err := api.SubsonicGetPlaylistSongs(id)
		if err != nil {
			return errMsg{err}
		}

		if shuffled {
			return shuffledSongsMsg{songs, true}
		} else {
			return songsResultMsg{songs}
		}
	}
}

func getStarredCmd() tea.Cmd {
	return func() tea.Msg {
		result, err := api.SubsonicGetStarred()
		if err != nil {
			return errMsg{err}
		}
		return starredResultMsg{result}
	}
}

func openLikedSongsCmd() tea.Cmd {
	return func() tea.Msg {
		result, err := api.SubsonicGetStarred()
		if err != nil {
			return errMsg{err}
		}

		return viewStarredSongsMsg(result)
	}
}

func toggleStarCmd(idsToStar []string, idsToUnstar []string) tea.Cmd {
	return func() tea.Msg {
		go api.SubsonicStar(idsToStar)
		go api.SubsonicUnstar(idsToUnstar)
		return nil
	}
}

func getCoverArtCmd(songID string) tea.Cmd {
	return func() tea.Msg {
		imgData, err := api.SubsonicCoverArt(songID, 500)
		if err != nil {
			return nil
		}

		img, _, err := image.Decode(bytes.NewReader(imgData))
		if err != nil {
			return nil
		}

		return coverArtMsg{
			img: img,
		}
	}
}

func getPlayQueue() tea.Cmd {
	return func() tea.Msg {
		result, err := api.SubsonicGetQueue()
		if err != nil {
			return errMsg{err}
		}
		return playQueueResultMsg{result}
	}

}

func savePlayQueueCmd(ids []string, currentID string) tea.Cmd {
	return func() tea.Msg {

		if len(ids) != 0 {
			api.SubsonicSaveQueue(ids, currentID)
		}

		return nil
	}
}

func addSongToPlaylistCmd(playlistID string, songIds []string) tea.Cmd {
	return func() tea.Msg {

		if playlistID == "" || len(songIds) == 0 {
			return nil
		}

		api.SubsonicAddToPlaylist(playlistID, songIds)
		return nil
	}
}

func addRatingCmd(ids []string, rating int) tea.Cmd {
	return func() tea.Msg {
		if rating >= 00 && rating <= 5 && len(ids) > 0 {
			for i := range ids {
				go api.SubsonicRate(ids[i], rating)
			}
		}

		return nil
	}
}

func createMediaShareCmd(ids []string) tea.Cmd {
	return func() tea.Msg {

		if len(ids) > 0 {
			url, err := api.SubsonicCreateShare(ids)
			if err != nil {
				return errMsg{err}
			}

			return createShareMsg{url: url}
		}
		return nil
	}
}

func getLyricsCmd(ID string) tea.Cmd {
	return func() tea.Msg {
		if ID != "" {
			result, err := api.SubsonicGetLyrics(ID)

			if err != nil {
				return errMsg{err}
			}
			return getLyricsMsg{result}
		}

		return nil
	}
}
