var _ = require('underscore');
var ko = require('knockout');
var moment = require('moment-timezone');
var dom = require('../lib/dom');
var dispose = require('../lib/dispose');
var kd = require('../lib/koDom');
var kf = require('../lib/koForm');
var DateTextBox = require('./DateTextBox');
var gutil = require('app/common/gutil');

const {fromKoSave} = require('app/client/lib/fromKoSave');
const {alignmentSelect, cssButtonSelect} = require('app/client/ui2018/buttonSelect');
const {cssRow, cssLabel} = require('app/client/ui/RightPanelStyles');
const {cssTextInput} = require("app/client/ui2018/editableLabel");
const {dom: gdom, styled, fromKo} = require('grainjs');
const {select} = require('app/client/ui2018/menus');
const {buildTZAutocomplete} = require('app/client/widgets/TZAutocomplete');
const {timeFormatOptions} = require("app/common/parseDate");


/**
 * DateTimeTextBox - The most basic widget for displaying date and time information.
 */
function DateTimeTextBox(field) {
  DateTextBox.call(this, field);

  // Returns the timezone from the end of the type string
  this._timezone = this.autoDispose(ko.computed(() =>
    gutil.removePrefix(field.column().type(), "DateTime:")));

  this._setTimezone = (val) => field.column().type.setAndSave('DateTime:' + val);

  this.timeFormat = this.field.config.options.prop('timeFormat');
  this.isCustomTimeFormat = this.field.config.options.prop('isCustomTimeFormat');
  this.mixedTimeFormat = ko.pureComputed(() => this.timeFormat() === null || this.isCustomTimeFormat() === null);

  // Helper to set 'timeFormat' and 'isCustomTimeFormat' from the set of default time format strings.
  this.standardTimeFormat = this.autoDispose(ko.computed({
    owner: this,
    read: function() { return this.isCustomTimeFormat() ? 'Custom' : this.timeFormat(); },
    write: function(val) {
      if (val === 'Custom') { this.isCustomTimeFormat.setAndSave(true); }
      else {
        this.isCustomTimeFormat.setAndSave(false);
        this.timeFormat.setAndSave(val);
      }
    }
  }));
}
dispose.makeDisposable(DateTimeTextBox);
_.extend(DateTimeTextBox.prototype, DateTextBox.prototype);

/**
 * Builds the config dom for the DateTime TextBox. If isTransformConfig is true,
 * builds only the necessary dom for the transform config menu.
 */
DateTimeTextBox.prototype.buildConfigDom = function(_gristDoc, isTransformConfig) {
  const disabled = ko.pureComputed(() => {
    return this.field.config.options.disabled('timeFormat')() || this.field.column().disableEditData();
  });
  const alignment = fromKoSave(this.field.config.options.prop('alignment'));
  return dom('div',
    cssLabel("Timezone"),
    cssRow(
      gdom.create(buildTZAutocomplete, moment, fromKo(this._timezone), this._setTimezone,
        { disabled : fromKo(disabled)}),
      ),
    this.buildDateConfigDom(),
    cssLabel("Time Format"),
    cssRow(dom(
      select(
        fromKo(this.standardTimeFormat),
        [...timeFormatOptions, "Custom"],
        { disabled : fromKo(disabled), defaultLabel: 'Mixed format' }
      ),
      dom.testId("Widget_timeFormat")
    )),
    kd.maybe(() => !this.mixedTimeFormat() && this.isCustomTimeFormat(), () => {
      return cssRow(
        dom(
          textbox(this.timeFormat, { disabled: this.field.config.options.disabled('timeFormat')}),
          dom.testId("Widget_timeCustomFormat")
        )
      );
    }),
    isTransformConfig ? null : cssRow(
      alignmentSelect(
        alignment,
        cssButtonSelect.cls('-disabled', this.field.config.options.disabled('alignment')),
      )
    )
  );
};

DateTimeTextBox.prototype.buildTransformConfigDom = function(gristDoc) {
  return this.buildConfigDom(gristDoc, true);
};

// clean up old koform styles
const cssClean = styled('div', `
  flex: 1;
  margin: 0px;
`)

// override focus - to look like modern ui
const cssFocus = styled('div', `
  &:focus {
    outline: none;
    box-shadow: 0 0 3px 2px #5e9ed6;
    border: 1px solid transparent;
  }
`)


// helper method to create old style textbox that looks like a new one
function textbox(value, options) {
  const textDom = kf.text(value, options || {});
  const tzInput = textDom.querySelector('input');
  dom(tzInput,
    kd.cssClass(cssTextInput.className),
    kd.cssClass(cssFocus.className)
  );
  dom(textDom,
    kd.cssClass(cssClean.className)
  );
  return textDom;
}

module.exports = DateTimeTextBox;
