{Flux} = require 'delorean'
_ = require 'lodash'

Validation = Flux.createStore
  
  actions: 
    'add-error': 'addError'
    'toggle-error': 'toggleError'
    'clear-error': 'clearError'
    'clear-all': 'clearAll'
    'force-show-all': 'forceShowAll'
    'reset-force-show-all': 'resetForceShowAll'
    'user-logout': 'clearData'

  clearData: -> @resetState()

  scheme:
    #-------------------- Regular Errors  
    errors:
      default: {}
    errorsActive:
      default: no
    forceShowAllErrors:
      default: no
    #-------------------- PVR Errors
    pvrErrors:
      default: {}
    pvrErrorsActive:
      default: no
    pvrForceShowAllErrors:
      default: no

  ###
  Error Object Specs
  Each object represents a field, and contains all the active validation issues for that field
  {
    show: yes/no - whether or not the message displaying in the UI
    autoHideAfter: Int - ms to hide the error after
    direction: 'left/right/above/below' - defaults to below - direction of the message pvr
    messages: [] - array of error message strings
  }

  ###


  addError: (options) ->
    {isInPopover} = options
    
    if isInPopover then @addPvrError(options) else @addRegularError(options)


  addRegularError: (options) ->
    {groupId, error, anchor} = options
    {errors} = @state

    errors[groupId] = error
    errors[groupId].anchor = anchor
    errors[groupId].direction = 'below' unless error.direction?

    @set
      errorsActive: yes

    if error.autoHideAfter then @autoHide error, groupId


  addPvrError: (options) ->
    {groupId, error, anchor} = options
    {pvrErrors} = @state

    pvrErrors[groupId] = error
    pvrErrors[groupId].anchor = anchor
    pvrErrors[groupId].direction = 'below' unless error.direction?

    @set
      pvrErrorsActive: yes

    if error.autoHideAfter then @autoHide error, groupId

  clearError: (options) ->
    {isInPopover} = options

    if isInPopover then @clearPvrError(options) else @clearRegularError(options)

  clearRegularError: (options) ->
    {groupId} = options
    {errors} = @state

    if errors[groupId]?
      delete errors[groupId]
      @set
        errorsActive: Object.keys(errors).length > 0

  clearPvrError: (options) ->
    {groupId} = options
    {pvrErrors} = @state

    if pvrErrors[groupId]?
      delete pvrErrors[groupId]
      @set
        errorsActive: Object.keys(pvrErrors).length > 0

  clearAll: (isInPopover) -> 
    if isInPopover then @clearAllPvrErrors() else @clearAllRegularErrors()

  clearAllRegularErrors: ->
    @set
      errors: {}
      errorsActive: no
      forceShowAllErrors: no

  clearAllPvrErrors: ->
    @set
      pvrErrors: {}
      pvrErrorsActive: no
      pvrForceShowAllErrors: no

  toggleError: (options) ->
    {groupId, status, isMouseOver, isInPopover} = options
    {errors, pvrErrors} = @state
    error = if isInPopover then pvrErrors[groupId] else errors[groupId]

    if not error? then return
    else
      error.show = if status? then status else yes
      @emit 'change'
      @autoHide error, groupId if not isMouseOver and error.autoHideAfter


  forceShowAll: (options) ->
    {autoHideAfter, isInPopover} = options

    if isInPopover then @forceShowAllPvr(autoHideAfter) else @forceShowAllRegular(autoHideAfter)

  forceShowAllRegular: (autoHideAfter) ->
    {errors} = @state

    error.show = yes for groupId, error of errors

    @set
      forceShowAllErrors: yes

    @autoHideAll(errors) if autoHideAfter

  forceShowAllPvr: (autoHideAfter) ->
    {pvrErrors} = @state

    error.show = yes for groupId, error of pvrErrors

    @set
      pvrForceShowAllErrors: yes

    @autoHideAll(pvrErrors) if autoHideAfter

  resetForceShowAll: ->
    @set 
      forceShowAllErrors: no
      pvrForceShowAllErrors: no

  hideAll: (errors) ->
    error.show = no for groupId, error of errors
      
    @emit 'change'

  hideTimers: {}

  autoHide: (error, groupId) ->
    clearInterval @hideTimers[groupId]

    @hideTimers[groupId] = setTimeout =>
      error.show = no
      @emit 'change'
    , error.autoHideAfter or 1500

  autoHideAll: (errors) ->
    clearInterval @hideAllTimer

    @hideAllTimer = setTimeout =>
      @hideAll(errors)
    , 1500



module.exports = Validation


