'use strict'

### COMMON CODE ###



class PlanController

  constructor: ($scope, groups, prices, partners, CSRF) ->
    # protection against request forgery
    CSRF.setMetaTags()



    ## groups list
    $scope.groups = groups

    ## users with role 'partner', notifiables for a partner plan
    $scope.partners = partners.users

    ## Subscriptions prices, machines prices and training prices, per groups
    $scope.group_pricing = prices

    ##
    # For use with 'ng-class', returns the CSS class name for the uploads previews.
    # The preview may show a placeholder or the content of the file depending on the upload state.
    # @param v {*} any attribute, will be tested for truthiness (see JS evaluation rules)
    ##
    $scope.fileinputClass = (v)->
      if v
        'fileinput-exists'
      else
        'fileinput-new'

    ##
    # Mark the provided file for deletion
    # @param file {Object}
    ##
    $scope.deleteFile = (file) ->
      if file? and file.id?
        file._destroy = true



##
# Controller used in the plan creation form
##
Application.Controllers.controller 'NewPlanController', ['$scope', '$uibModal', 'groups', 'prices', 'partners', 'CSRF', '$state', 'growl', '_t'
, ($scope, $uibModal, groups, prices, partners, CSRF, $state, growl, _t) ->



  ### PRIVATE STATIC CONSTANTS ###

  ## when creating a new contact for a partner plan, this ID will be sent to the server
  NEW_PARTNER_ID: null



  ### PUBLIC SCOPE ###

  ## current form is used to create a new plan
  $scope.mode = 'creation'

  ## prices bindings
  $scope.prices =
    training: {}
    machine: {}

  ## form inputs bindings
  $scope.plan =
    type: null
    group_id: null
    interval: null
    intervalCount: 0
    amount: null
    isRolling: false
    partnerId: null
    partnerContact: null
    ui_weight: 0

  ## API URL where the form will be posted
  $scope.actionUrl = "/api/plans/"

  ## HTTP method for the rest API
  $scope.method = 'POST'



  ##
  # Checks if the partner contact is a valid data. Used in the form validation process
  # @returns {boolean}
  ##
  $scope.partnerIsValid = ->
    ($scope.plan.type == "Plan") or ($scope.plan.partnerId or ($scope.plan.partnerContact and $scope.plan.partnerContact.email))



  ##
  # Open a modal dialog allowing the admin to create a new partner user
  ##
  $scope.openPartnerNewModal = (subscription)->
    modalInstance = $uibModal.open
      animation: true,
      templateUrl: '<%= asset_path "shared/_partner_new_modal.html" %>'
      size: 'lg',
      controller: ['$scope', '$uibModalInstance', 'User', ($scope, $uibModalInstance, User) ->
        $scope.partner = {}

        $scope.ok = ->
          User.save {}, { user: $scope.partner }, (user)->
            $scope.partner.id = user.id
            $scope.partner.name = "#{user.first_name} #{user.last_name}"
            $uibModalInstance.close($scope.partner)
          , (error)->
            growl.error(_t('new_plan.unable_to_save_this_user_check_that_there_isnt_an_already_a_user_with_the_same_name'))
        $scope.cancel = ->
          $uibModalInstance.dismiss('cancel')
      ]
    # once the form was validated succesfully ...
    modalInstance.result.then (partner) ->
      $scope.partners.push(partner)
      $scope.plan.partnerId = partner.id



  ##
  # Display some messages and redirect the user, once the form was submitted, depending on the result status
  # (failed/succeeded).
  # @param content {Object}
  ##
  $scope.afterSubmit = (content) ->
    if !content.id? and !content.plan_ids?
      growl.error(_t('new_plan.unable_to_create_the_subscription_please_try_again'))
    else
      growl.success(_t('new_plan.successfully_created_subscription(s)_dont_forget_to_redefine_prices'))
      if content.plan_ids?
        $state.go('app.admin.pricing')
      else
        if content.id?
          $state.go('app.admin.plans.edit', {id: content.id})



  new PlanController($scope, groups, prices, partners, CSRF)
]



##
# Controller used in the plan edition form
##
Application.Controllers.controller 'EditPlanController', ['$scope', 'groups', 'plans', 'planPromise', 'machines', 'spaces', 'prices', 'partners', 'CSRF', '$state', '$stateParams', 'growl', '$filter', '_t', 'Plan'
, ($scope, groups, plans, planPromise, machines, spaces, prices, partners, CSRF, $state, $stateParams, growl, $filter, _t, Plan) ->



  ### PUBLIC SCOPE ###

  ## List of spaces
  $scope.spaces = spaces

  ## List of plans
  $scope.plans = plans

  ## List of machines
  $scope.machines = machines

  ## List of groups
  $scope.groups = groups

  ## current form is used for edition mode
  $scope.mode = 'edition'

  ## edited plan data
  $scope.plan = planPromise
  $scope.plan.type = "Plan" if $scope.plan.type == null

  ## API URL where the form will be posted
  $scope.actionUrl = "/api/plans/" + $stateParams.id

  ## HTTP method for the rest API
  $scope.method = 'PATCH'



  ##
  # If a parent plan was set ($scope.plan.parent), the prices will be copied from this parent plan into
  # the current plan prices list. Otherwise, the current plan prices will be erased.
  ##
  $scope.copyPricesFromPlan = ->
    if $scope.plan.parent
      Plan.get {id: $scope.plan.parent}, (parentPlan) ->
        for parentPrice in parentPlan.prices
          for childKey, childPrice of $scope.plan.prices
            if childPrice.priceable_type == parentPrice.priceable_type and childPrice.priceable_id == parentPrice.priceable_id
              $scope.plan.prices[childKey].amount = parentPrice.amount
              break

    # if no plan were selected, unset every prices
    else
      for key, price of $scope.plan.prices
        $scope.plan.prices[key].amount = 0



  ##
  # Display some messages once the form was submitted, depending on the result status (failed/succeeded)
  # @param content {Object}
  ##
  $scope.afterSubmit = (content) ->
    if !content.id? and !content.plan_ids?
      growl.error(_t('edit_plan.unable_to_save_subscription_changes_please_try_again'))
    else
      growl.success(_t('edit_plan.subscription_successfully_changed'))
      $state.go('app.admin.pricing')



  ##
  # Generate a string identifying the given plan by literal humain-readable name
  # @param plan {Object} Plan object, as recovered from GET /api/plan/:id
  # @param groups {Array} List of Groups objects, as recovered from GET /api/groups
  # @param short {boolean} If true, the generated name will contains the group slug, otherwise the group full name
  # will be included.
  # @returns {String}
  ##
  $scope.humanReadablePlanName = (plan, groups, short)->
    "#{$filter('humanReadablePlanName')(plan, groups, short)}"



  ##
  # Retrieve the name of a machine from its ID
  # @param machine_id {number} machine identifier
  # @returns {string} Machine's name
  ##
  $scope.getMachineName = (machine_id) ->
    for machine in $scope.machines
      if machine.id == machine_id
        return machine.name



  ##
  # Retrieve the name of a space from its ID
  # @param space_id {number} space identifier
  # @returns {string} Space's name
  ##
  $scope.getSpaceName = (space_id) ->
    for space in $scope.spaces
      if space.id == space_id
        return space.name



  ### PRIVATE SCOPE ###

  ##
  # Kind of constructor: these actions will be realized first when the controller is loaded
  ##
  initialize = ->
    # Using the PlansController
    new PlanController($scope, groups, prices, partners, CSRF)

  ## !!! MUST BE CALLED AT THE END of the controller
  initialize()
]
