content: /*
   * Copyright (C) 2015 - present Instructure, Inc.
   *
   * This file is part of Canvas.
   *
   * Canvas is free software: you can redistribute it and/or modify it under
   * the terms of the GNU Affero General Public License as published by the Free
   * Software Foundation, version 3 of the License.
   *
   * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
   * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
   * details.
   *
   * You should have received a copy of the GNU Affero General Public License along
   * with this program. If not, see <http://www.gnu.org/licenses/>.
   */
  
  import $ from 'jquery'
  import React from 'react'
  import PropTypes from 'prop-types'
  import accessibleDateFormat from '../shared/helpers/accessibleDateFormat'
  import shortId from '../shared/shortid'
  import tz from 'timezone'
  import 'jquery.instructure_forms'
  import cx from 'classnames'
  
  const {string, func, bool, instanceOf, oneOfType} = PropTypes
  
  class DueDateCalendarPicker extends React.Component {
    static propTypes = {
      dateType: string.isRequired,
      handleUpdate: func.isRequired,
      rowKey: string.isRequired,
      labelledBy: string.isRequired,
      inputClasses: string.isRequired,
      disabled: bool.isRequired,
      isFancyMidnight: bool.isRequired,
      defaultToEndOfMinute: bool,
      dateValue: oneOfType([instanceOf(Date), string]).isRequired,
      labelText: string.isRequired,
      labelClasses: string,
      name: string,
      readonly: bool
    }
  
    static defaultProps = {
      readonly: false,
      defaultToEndOfMinute: false,
      labelClasses: ''
    }
  
    constructor(props) {
      super(props)
      this.uniqueId = shortId()
      this.state = {}
    }
  
    // ---------------
    //    Lifecycle
    // ---------------
  
    componentDidMount() {
      const dateInput = this.refs.dateInput
  
      $(dateInput)
        .datetime_field()
        .change(e => {
          const trimmedInput = $.trim(e.target.value)
  
          let newDate = $(dateInput).data('unfudged-date')
          newDate = trimmedInput === '' ? null : newDate
          newDate = this.changeToFancyMidnightIfNeeded(newDate)
          newDate = this.setToEndOfMinuteIfNeeded(newDate)
  
          this.props.handleUpdate(newDate)
        })
    }
  
    // ensure jquery UI updates (as react doesn't know about it)
    componentDidUpdate() {
      const dateInput = this.refs.dateInput
      $(dateInput).val(this.formattedDate())
    }
  
    changeToFancyMidnightIfNeeded = date => {
      if (this.props.isFancyMidnight && tz.isMidnight(date)) {
        return tz.changeToTheSecondBeforeMidnight(date)
      }
  
      return date
    }
  
    setToEndOfMinuteIfNeeded = date => {
      if (this.props.defaultToEndOfMinute && tz.format(date, '%S') === '00') {
        return tz.setToEndOfMinute(date)
      }
  
      return date
    }
  
    // ---------------
    //    Rendering
    // ---------------
  
    formattedDate = () => {
      // make this match the format used by the datepicker
      const dateStr = $.dateString(this.props.dateValue)
      const timeStr = $.timeString(this.props.dateValue)
      return `${dateStr} ${timeStr}`
    }
  
    wrapperClassName = () =>
      this.props.dateType == 'due_at' ? 'DueDateInput__Container' : 'DueDateRow__LockUnlockInput'
  
    render() {
      if (this.props.disabled || this.props.readonly) {
        const className = cx('ic-Form-control', {readonly: this.props.readonly})
        return (
          <div className={className}>
            <label className={`${this.props.labelClasses} ic-Label`} htmlFor={this.props.dateType}>
              {this.props.labelText}
            </label>
            <div className="ic-Input-group">
              <input
                id={this.props.dateType}
                name={this.props.name}
                readOnly
                type="text"
                className={`ic-Input ${this.props.inputClasses}`}
                defaultValue={this.formattedDate()}
              />
              {this.props.readonly ? null : (
                <div
                  className="ic-Input-group__add-on"
                  role="presentation"
                  aria-hidden="true"
                  tabIndex="-1"
                >
                  <button
                    className="Button Button--icon-action disabled"
                    aria-disabled="true"
                    type="button"
                  >
                    <i className="icon-calendar-month" role="presentation" />
                  </button>
                </div>
              )}
            </div>
          </div>
        )
      }
  
      return (
        <div>
          <label
            id={this.props.labelledBy}
            className={`${this.props.labelClasses} Date__label`}
            htmlFor={this.uniqueId}
          >
            {this.props.labelText}
          </label>
          <div ref="datePickerWrapper" className={this.wrapperClassName()}>
            <input
              id={this.uniqueId}
              name={this.props.name}
              type="text"
              ref="dateInput"
              title={accessibleDateFormat()}
              data-tooltip=""
              className={this.props.inputClasses}
              aria-labelledby={this.props.labelledBy}
              data-row-key={this.props.rowKey}
              data-date-type={this.props.dateType}
              defaultValue={this.formattedDate()}
            />
          </div>
        </div>
      )
    }
  }
  
  export default DueDateCalendarPicker
  