const m = require('mithril')
const api = require('./api')
const tempus = require('@eonasdan/tempus-dominus')

const tempusLocalization = {
  locale: 'is',
  startOfTheWeek: 0,
  hourCycle: 'h23',
  dateFormats: {
    LTS: 'H:mm:ss',
    LT: 'H:mm',
    L: 'dd.MM.yyyy',
    LL: 'd [de] MMMM [de] yyyy',
    LLL: 'd [de] MMMM [de] yyyy H:mm',
    LLLL: 'dddd, d [de] MMMM [de] yyyy H:mm',
  },
}

const Input = {
  oninit: function(vnode) {
    this.tempus = null
    this.subscription = null
    this.input = null
    this.preview = null
  },

  onremove: function(vnode) {
    if (this.subscription) this.subscription.unsubscribe()
    if (this.tempus) {
      this.tempus.dispose()
      this.tempus = null
    }
    if (this.preview) {
      this.preview.clear()
    }
  },

  onupdate: function(vnode) {
    if (this.tempus && vnode.attrs.form[vnode.attrs.formKey]) {
      if (vnode.attrs.form[vnode.attrs.formKey].getTime() !== this.tempus.viewDate?.getTime()) {
        this.tempus.dates.setValue(new tempus.DateTime(vnode.attrs.form[vnode.attrs.formKey]))
      }
    }
  },

  imageChanged: function(vnode, e) {
    let file = e.currentTarget.files?.[0] || null
    this.updateValue(vnode, file)
    if (this.preview) {
      this.preview.clear()
      this.preview = null
    }
    if (!file) return

    if (file.type.startsWith('image')) {
      this.preview = {
        file: file,
        preview: URL.createObjectURL(file),
        clear: function() {
          URL.revokeObjectURL(this.preview)
        },
      }
    }
  },

  updateValue: function(vnode, value) {
    vnode.attrs.form[vnode.attrs.formKey] = value
    if (typeof(vnode.attrs.oninput) === 'function') {
      vnode.attrs.oninput(vnode.attrs.form[vnode.attrs.formKey])
    }
    return false
  },

  getInput: function(vnode) {
    switch (vnode.attrs.utility) {
      case 'file':
        return m('div.form-row', [
          m('input', {
            type: 'text',
            disabled: api.loading,
            value: vnode.attrs.form[vnode.attrs.formKey]?.name || '',
          }),
          m('button.fal', { class: vnode.attrs.button || 'file' }),
          m('input.cover', {
            type: 'file',
            accept: vnode.attrs.accept,
            disabled: api.loading,
            oninput: (e) => this.updateValue(vnode, e.currentTarget.files?.[0] || null),
          }),
        ])
      case 'datetime':
        return m('div.form-row', [
          m('input', {
            type: 'text',
            disabled: api.loading,
            oncreate: (e) => {
              this.tempus = new tempus.TempusDominus(e.dom, {
                localization: tempusLocalization,
              })
              this.tempus.dates.setValue(new tempus.DateTime(vnode.attrs.form[vnode.attrs.formKey]))
              this.subscription = this.tempus.subscribe(tempus.Namespace.events.change, (e) => {
                this.updateValue(vnode, e.date)
              });
            },
          }),
          m('button.fal.fa-calendar', {
            onclick: () => { this.tempus.toggle(); return false },
          })
        ])
      case 'image':
        let imageLink = this.preview && this.preview.preview || vnode.attrs.form[vnode.attrs.formKey]

        return m('div.form-row.image-banner', {
          style: {
            'background-image': typeof imageLink === 'string' ? 'url("' + (imageLink) + '")' : null,
          },
        }, [
          m('input.cover', {
            type: 'file',
            accept: vnode.attrs.accept,
            disabled: api.loading,
            onchange: this.imageChanged.bind(this, vnode),
          }),
        ])
      default:
        return m('input', {
          disabled: api.loading,
          type: vnode.attrs.type || 'text',
          value: vnode.attrs.form[vnode.attrs.formKey],
          oninput: (e) => this.updateValue(vnode, e.currentTarget.value),
        })
    }
  },

  view: function(vnode) {
    return [
      vnode.attrs.label ? m('label', vnode.attrs.label) : null,
      this.getInput(vnode),
    ]
  },
}

module.exports = Input
