using System.Threading.Tasks; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.EntityFrameworkCore; using Microsoft.VisualBasic; namespace sotd.Pages; public class SongSubmissionModel : PageModel { private readonly ILogger _logger; private SongResolver songResolver; private string _submitUrl; private SpotifyApiClient spotifyApiClient; private SignalIntegration signalIntegration; public SongSubmissionModel(ILogger logger, SongResolver songResolver, SpotifyApiClient spotifyApiClient, SignalIntegration signalIntegration) { _logger = logger; this.spotifyApiClient = spotifyApiClient; this.songResolver = songResolver; this.signalIntegration = signalIntegration; _submitUrl = string.Empty; SongData = new Song(); } [Parameter] public int? SubmissionIndex { get; set; } [BindProperty] public bool IsValidUrl { get; set; } = true; [BindProperty] public bool IsPageReadonly { get; set; } = false; [BindProperty] public SuggestionHelper SuggestionHelper { get; set; } = null; [BindProperty] public List UserSongSubmissions { get; set; } = []; [BindProperty(SupportsGet = true)] public string SubmitUrl { get { return _submitUrl; } set { _submitUrl = value == null ? string.Empty : value.ToString(); Uri? newValue = default; try { newValue = new Uri(_submitUrl); } catch (UriFormatException) { IsValidUrl = false; return; } IsValidUrl = true; if (this.songResolver.CanValidate(newValue)) { this.SongData = this.songResolver.ResolveSongAsync(newValue).Result; } } } public List SpotifySuggestions { get { var suggestionList = new List(); if (!string.IsNullOrEmpty(this.SongData.Name) && !string.IsNullOrEmpty(this.SongData.Artist)) { suggestionList.AddRange(spotifyApiClient.GetTrackCandidatesAsync(this.SongData.Name, this.SongData.Artist).Result); } return suggestionList; } } public IActionResult OnGetSpotifySuggestions(string song, string artist, string submitUrl, SongProvider provider, string spotifyId) { this.SongData.Name = song; this.SongData.Artist = artist; this.SongData.Url = submitUrl; this.SongData.Provider = provider; this.SongData.SpotifyId = spotifyId; return Partial("_SpotifySongSuggestionsPartial", this.SpotifySuggestions); } [BindProperty] public string CanSubmit { get { var disableCondition = !(string.IsNullOrEmpty(SongData?.Artist) && string.IsNullOrEmpty(SongData?.Name)); return disableCondition ? "" : "disabled"; } } [BindProperty(SupportsGet = true)] public Song SongData { get; set; } [BindProperty(SupportsGet = true)] public bool HasUsedSuggestion { get; set; } = true; private async Task UpdateGroup(SongSuggestion suggestion) { var isItToday = suggestion.Date.Date == DateTime.Today; var dateString = isItToday ? "submission for today" : "submission from " + suggestion.Date.ToString("dd. MM. yyyy"); var displayName = string.IsNullOrEmpty(suggestion.User.NickName) ? suggestion.User.Name : suggestion.User.NickName; var imageBuilder = await songResolver.GetPreviewImageAsync(suggestion.Song.SpotifyId); var previewData = new LinkPreviewAttachment() { Title = suggestion.Song.Name, Description = suggestion.Song.Artist, Url = suggestion.Song.Url, Base64Image = imageBuilder.ToString(), }; await signalIntegration.SendMessageToGroupAsync($"**{displayName}**'s " + dateString + $" is: \n\n {suggestion.Song.Url}", previewData); if (suggestion.HasUsedSuggestion) { await signalIntegration.SendMessageToGroupAsync($"The suggestion used for this pick was: \n\n **{suggestion.SuggestionHelper.Title}**'s \n\n {suggestion.SuggestionHelper.Description}"); } } public async Task OnPost(int? submissionIndex) { if (submissionIndex == null) { throw new Exception("Attempt to submit song without submissionId"); } // Todo implement save submission using var dci = DataContext.Instance; var suggestion = dci.SongSuggestions .Include(s => s.User) .Include(s => s.SuggestionHelper) .Where(s => s.Id == submissionIndex) .FirstOrDefault(); if (suggestion == null) { throw new Exception("Attempt to submit song with invalid submissionId"); } this.SongData.Artist = Request.Form["Artist"]; this.SongData.Url = Request.Form["SubmitUrl"]; this.SongData.Name = Request.Form["Name"]; this.SongData.SpotifyId = Request.Form["SpotifyId"]; this.SongData.Provider = Enum.Parse(Request.Form["Provider"]); // Let's check if we already have this song in the DB var songToUse = dci.Songs.Where(s => s.SpotifyId == this.SongData.SpotifyId).FirstOrDefault(); if (songToUse == null) { // Song was not in DB yet, creating a new one var newSong = new Song() { SpotifyId = this.SongData.SpotifyId, Artist = this.SongData.Artist, Name = this.SongData.Name, Url = this.SongData.Url, Provider = this.SongData.Provider, }; var dbRecord = dci.Songs.Add(newSong); var newId = await dci.SaveChangesAsync(); songToUse = dbRecord.Entity; } suggestion.Song = songToUse; suggestion.UserHasSubmitted = true; suggestion.HasUsedSuggestion = this.HasUsedSuggestion; dci.Update(suggestion); await dci.SaveChangesAsync(); // load overview page again after submitting await UpdateGroup(suggestion); return RedirectToPage("SongSubmission"); } public void OnGet(int? submissionIndex) { this.SubmissionIndex = submissionIndex; // we want to show overview, so we need to fetch user submission list if (submissionIndex == null) { using var dci = DataContext.Instance; var currentUserName = this.User.Identity.Name; this.UserSongSubmissions = dci.SongSuggestions .Include(s => s.SuggestionHelper) .Include(s => s.Song) .Where(s => s.User.LdapUserName.Equals(currentUserName)) .OrderByDescending(s => s.Date) .ToList(); } else { using var dci = DataContext.Instance; var songSuggestion = dci.SongSuggestions .Include(s => s.SuggestionHelper) .Include(s => s.Song) .Where(s => s.Id.Equals(submissionIndex.Value)) .First(); this.SuggestionHelper = songSuggestion.SuggestionHelper; this.SongData = songSuggestion.Song == null ? new Song() : songSuggestion.Song; this.SubmitUrl = this.SongData.Url; if (!string.IsNullOrEmpty(this.SongData.Name) && !string.IsNullOrEmpty(this.SongData.Artist)) { this.IsPageReadonly = true; } } } public IActionResult OnGetUpdate() { var songUrl = Request.Query["SubmitUrl"]; this.SubmitUrl = songUrl.ToString(); var songPartialModel = new SongPartialModel() { InnerSong = SongData, IsPageReadonly = false }; return Partial("_SongPartial", songPartialModel); ; } }