React = require 'react'
createClass = require 'create-react-class'
PropTypes = require 'prop-types'
ReactDatepicker = React.createFactory(require('react-datepicker').default)
moment = require 'moment'
assign = require 'lodash/assign'
InputMixin = require '../mixins/input_mixin'

{div, span} = require 'react-dom-factories'


DatePicker = createClass

  displayName: 'DatePicker'

  mixins: [InputMixin]

  contextTypes:
    clearValidationError: PropTypes.func
    addValidationError: PropTypes.func
    getValidationStatus: PropTypes.func
    toggleValidationError: PropTypes.func

  propTypes:
    placeholderText: PropTypes.oneOfType [
      PropTypes.string
      PropTypes.number
    ]
    dateFormat: PropTypes.string
    wrapperClass: PropTypes.string
    className: PropTypes.string
    minDate: PropTypes.object
    maxDate: PropTypes.object
    onChange: PropTypes.func.isRequired
    tabIndex: PropTypes.number
    hasDefaultDate: PropTypes.bool
    validation: PropTypes.oneOfType [
      PropTypes.object
      PropTypes.func
    ]
    selected: PropTypes.oneOfType [
      PropTypes.string
      PropTypes.object
    ]

  getDefaultProps: ->
    hasDefaultDate: yes # yes to have a default date in the date picker
    placeholderText: 'Select a date'
    dateFormat: 'MM/DD/YYYY'
    className: null
    includeTime: no # yes to include time selection
    returnDateString: null # pass a date format string to get that format from the getValue method
    onChange: ->

  getInitialState: ->
    selected: null

  componentWillMount: ->
    {hasDefaultDate} = @props

    # set initial state for selected
    # if selected is in props and hasDefaultDate value then props.selected date else if hasDefaultDate then today's date else null
    if hasDefaultDate and @props.selected?
      selected = @props.selected
    else if hasDefaultDate
      selected = moment()
    else
      selected = null
    
    @setState
      selected: selected
    
  componentWillReceiveProps: (nextProps) ->
    if nextProps.selected?.format(@props.returnDateString or @props.dateFormat) isnt @props.selected?.format(@props.returnDateString or @props.dateFormat)
      @setState
        selected: nextProps.selected
    
  render: ->
    {error, forceShowAllErrors} = @context.getValidationStatus(@inputId)
    {valueHasChanged} = @state
    isValid = not error?

    props = assign {}, @props, 
      onChange: @handleDateChange
      onChangeRaw: @handleRawDateChange
      key: 'picker'
    
    {wrapperClass} = props
    
    mainClass = 'datepicker-wrapper'
    mainClass += " #{wrapperClass}" if wrapperClass?
    mainClass += ' invalid' if not isValid and (valueHasChanged or forceShowAllErrors)

    div {
      className: mainClass
    }, [
      ReactDatepicker(props)
      div {
        className: 'field-errors-show'
        key: 'textInputErrorsShow'
        ref: 'errorAnchor'
        onMouseOver: @handleErrorMouseOver
        onMouseOut: @handleErrorMouseOut
      }
    ]
  
  handleRawDateChange: (e) -> 
    {dateFormat, validation} = @props
    {valueHasChanged} = @state
    typedValue = e.target.value

    value = moment(typedValue, dateFormat)

    @validate(validation, value)

    @setState {valueHasChanged: yes} unless valueHasChanged
      

  handleDateChange: (date) ->
    {validation, jsonPath} = @props
    
    @validate(validation, date)
    
    @setState
      selected: date
      valueHasChanged: yes
    , =>
      @props.onChange?(date, jsonPath)

  getDateValue: ->
    {returnDateString, hasDefaultDate} = @props
    {selected} = @state

    # if hasDefaultDate is false and nothing is selected then return an empty string
    if returnDateString? and selected?
      selected.format(returnDateString) 
    else if selected?
      selected
    else if hasDefaultDate
      moment()
    else
      null   


module.exports = DatePicker
