using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using Serilog; using TINK.Model.Connector; using TINK.Model.MiniSurvey; using TINK.MultilingualResources; using TINK.Repository.Exception; using TINK.View; using TINK.ViewModel.MiniSurvey.Question; namespace TINK.ViewModel.MiniSurvey { public class MiniSurveyViewModel : ObservableCollection { /// Delegate to retrieve connected state. protected Func IsConnectedDelegate { get; } /// Provides a connector object. private Func ConnectorFactory { get; } /// /// Reference on view service to show modal notifications and to perform navigation. /// private IViewService ViewService { get; } private MiniSurveyModel MiniSurvey { get; } /// Constructs mini survey view model. /// Connects system to copri for purposes of requesting a bike/ cancel request. /// Interface to actuate methodes on GUI. public MiniSurveyViewModel( Func isConnectedDelegate, Func connectorFactory, IViewService viewService) { IsConnectedDelegate = isConnectedDelegate ?? throw new ArgumentException($"Can not instantiate {nameof(MiniSurveyViewModel)}-object. No connector available."); ConnectorFactory = connectorFactory ?? throw new ArgumentException($"Can not instantiate {nameof(MiniSurveyViewModel)}-object. No connector available."); ViewService = viewService ?? throw new ArgumentException($"Can not instantiate {nameof(MiniSurveyViewModel)}-object. No view available."); MiniSurvey = new MiniSurveyModel { Title = "Bitte unterstützen Sie unsere Begleitforschung", Subtitle = "Ihre drei Antworten werden anonym gespeichert.", Footer = "Herzlichen Dank und viel Spaß bei der nächsten Fahrt!" }; MiniSurvey.Questions.Add( "q1", new QuestionModel { Text = "1. Was war der Hauptzweck dieser Ausleihe?", Type = MiniSurveyModel.Type.SingleAnswer }); MiniSurvey.Questions.Add( "q2", new QuestionModel { Text = "2. Welches Verkehrsmittel hätten Sie ansonsten benutzt?", Type = MiniSurveyModel.Type.SingleAnswer }); MiniSurvey.Questions.Add( "q3", new QuestionModel { Text = "3. Haben Sie Anmerkungen oder Anregungen?", Type = MiniSurveyModel.Type.CustomText }); MiniSurvey.Questions["q1"].PossibleAnswers.Add("opt1", "a. Einkauf"); MiniSurvey.Questions["q1"].PossibleAnswers.Add("opt2", "b. Kinderbeförderung"); MiniSurvey.Questions["q1"].PossibleAnswers.Add("opt3", "c. Lastentransport"); MiniSurvey.Questions["q1"].PossibleAnswers.Add("opt4", "d. Freizeit"); MiniSurvey.Questions["q1"].PossibleAnswers.Add("opt5", "e. Ausprobieren"); MiniSurvey.Questions["q1"].PossibleAnswers.Add("opt6", "f. Sonstiges"); MiniSurvey.Questions["q2"].PossibleAnswers.Add("opt1", "a. Auto"); MiniSurvey.Questions["q2"].PossibleAnswers.Add("opt2", "b. Motorrad oder Motorroller"); MiniSurvey.Questions["q2"].PossibleAnswers.Add("opt3", "c. Bus oder Bahn"); MiniSurvey.Questions["q2"].PossibleAnswers.Add("opt4", "d. Eigenes Fahrrad"); MiniSurvey.Questions["q2"].PossibleAnswers.Add("opt5", "e. Zu Fuß"); MiniSurvey.Questions["q2"].PossibleAnswers.Add("opt6", "f. Keines (ich hätte die Fahrt sonst nicht gemacht)"); Title = MiniSurvey.Title; Subtitle = MiniSurvey.Subtitle; Footer = MiniSurvey.Footer; foreach (var question in MiniSurvey.Questions) { switch (question.Value.Type) { case MiniSurveyModel.Type.SingleAnswer: Add(new CheckOneViewModel( new KeyValuePair(question.Key, question.Value.Text), question.Value.PossibleAnswers)); break; case MiniSurveyModel.Type.CustomText: Add(new FreeTextViewModel(new KeyValuePair(question.Key, question.Value.Text))); break; default: break; } } } public string Title { get; set; } public string Subtitle { get; set; } public string Footer { get; set; } /// Processes request to perform a copri action (reserve bike and cancel reservation). public System.Windows.Input.ICommand OnButtonClicked => new Xamarin.Forms.Command(async () => { Log.ForContext().Information($"User result {this[0].Answer.Value}, {this[1].Answer.Value}"); var isConnected = IsConnectedDelegate(); try { await ConnectorFactory(isConnected).Command.DoSubmitMiniSurvey(this.ToDictionary(x => x.Question.Key, x => x.Answer.Key)); } catch (Exception exception) { if (exception is ResponseException copriException) { // Copri server is not reachable. Log.ForContext().Information("Submitting mini survay answer failed. COPRI returned an error."); } else { Log.ForContext().Error("Submitting mini survay answer failed. {@l_oException}", exception); } await ViewService.DisplayAlert( AppResources.ErrorReturnSubmitFeedbackTitle, AppResources.ErrorReturnSubmitFeedbackMessage, AppResources.MessageAnswerOk); } await ViewService.PopModalAsync(); }); } }