import assign from 'fast.js/object/assign';
import udc from 'udc';

function validateValue(...args) {
  const [
    workingValue, blurred, autoValidate, validate, inputElement, validator,
    ] = args;

  let isInvalid = false;

  const handleValidation = (workingValue !== `` || blurred) &&
    autoValidate || validate && inputElement;

  if (handleValidation && validator) {
    isInvalid = !validator(workingValue);
  } else if (handleValidation) {
    isInvalid = !inputElement.checkValidity();
  }

  return isInvalid;
}

function styleLabel(props, labelLeft) {
  let {label} = props;

  if (props.prefix) {
    label = udc(props.label);

    const labelAttributes = label.properties.attributes =
      label.properties.attributes || {};

    labelAttributes.style =
      `${labelAttributes.style || ``};${labelLeft}`.replace(/^;/, ``);
  }

  return label;
}

function model({props$, actions, layout, dialogueName}) {
  return props$.combineLatest(
    actions.focused$,
    actions.blurred$,
    actions.value$,
    layout.inputElement$,
    layout.floatLabelOffsetLeft$,
    (props, ...items) => {
      const [focused, blurred, value, inputElement, floatLabelOffsetLeft] =
        items;

      const {
        autoValidate,
        validate,
        disableLabelFloat,
        persistLabelFloat,
        bindValue,
        validator} = props;

      let workingValue = bindValue || value;

      const isInvalid = validateValue(
        workingValue, blurred, autoValidate, validate, inputElement, validator
      );

      // type="number" hack needed because value is empty until it’s valid.
      // See issue #25.
      const inputHasContent = workingValue || workingValue === 0 ||
        inputElement && inputElement.type === `number` &&
        !inputElement.checkValidity();

      const floatLabel =
        !disableLabelFloat && inputHasContent || persistLabelFloat;

      const labelLeft = floatLabel ? floatLabelOffsetLeft : `left: 0;`;

      const hideLabel = disableLabelFloat && inputHasContent;

      const label = styleLabel(props, labelLeft);

      const maxLength = props.maxLength ||
        inputElement && inputElement.maxlength;

      return assign({},
        props,
        {
          dialogueName,
          label,
          maxLength,
          focused,
          value,
          isInvalid,
          floatLabel,
          labelLeft,
          hideLabel,
        });
    }
  );
}

export default model;

@@ -1237,23 +1237,24 @@
         
-validat
+bindValu
 e,%0A     
@@ -1306,32 +1306,31 @@
 at,%0A        
-bindValu
+validat
 e,%0A        v
@@ -2074,100 +2074,8 @@
 );%0A%0A
-      const maxLength = props.maxLength %7C%7C%0A        inputElement && inputElement.maxlength;%0A%0A
     
@@ -2164,29 +2164,8 @@
 el,%0A
-          maxLength,%0A
     

remove get `maxLength` if unspecified