import 'package:comunic/models/api_request.dart';
import 'package:comunic/models/survey.dart';
import 'package:comunic/models/survey_choice.dart';
import 'package:meta/meta.dart';

/// Survey helper
///
/// @author Pierre HUBERT

class SurveyHelper {
  /// Get information about a single survey
  static Future<Survey> getSurveyInfo(int postID) async =>
      apiToSurvey((await APIRequest.withLogin("surveys/get_info")
              .addInt("postID", postID)
              .execWithThrow())
          .getObject());

  /// Cancel the response of a user to a survey
  Future<bool> cancelResponse(Survey survey) async {
    return (await APIRequest(
            uri: "surveys/cancel_response",
            needLogin: true,
            args: {"postID": survey.postID.toString()}).exec())
        .isOK;
  }

  /// Send the response of a user to a survey
  Future<bool> respondToSurvey(
      {@required Survey survey, @required SurveyChoice choice}) async {
    assert(survey != null);
    assert(choice != null);

    return (await APIRequest(
      uri: "surveys/send_response",
      needLogin: true,
      args: {
        "postID": survey.postID.toString(),
        "choiceID": choice.id.toString(),
      },
    ).exec())
        .isOK;
  }

  /// Create a new choice in a survey
  ///
  /// Throws in case of failure
  static Future<void> createNewChoice(int postID, String newChoice) async =>
      await APIRequest.withLogin("surveys/create_new_choice")
          .addInt("postID", postID)
          .addString("choice", newChoice)
          .execWithThrow();

  /// Prevent new choices from being created on a survey
  ///
  /// Throws in case of failure
  static Future<void> blockNewChoicesCreation(int postID) async =>
      await APIRequest.withLogin("surveys/block_new_choices_creation")
          .addInt("postID", postID)
          .execWithThrow();

  /// Turn an API entry into a [Survey] object
  static Survey apiToSurvey(Map<String, dynamic> map) {
    // Parse survey responses
    Set<SurveyChoice> choices = Set();

    map["choices"].forEach((k, e) => choices.add(SurveyChoice(
        id: e["choiceID"], name: e["name"], responses: e["responses"])));

    return Survey(
      id: map["ID"],
      userID: map["userID"],
      postID: map["postID"],
      creationTime: map["creation_time"],
      question: map["question"],
      userChoice: map["user_choice"],
      choices: choices,
      allowNewChoicesCreation: map["allowNewChoices"],
    );
  }
}