const m = require('mithril')
const api = require('./api')
const Authentication = require('./authentication')
const Input = require('./input')
const lang = require('./lang')
const videos = require('./videos')
const HoldButton = require('./holdbutton')

const Article = {
  oninit: function(vnode) {
    this.error = ''
    this.path = ''
    this.data = null
    this.editing = false
    this.cacheImage = null
    this.form = {
      title: 'Sunnudagssamkoma',
      date: new Date(),
      banner: null,
      metadata: {
        speaker: '',
      },
    }
    this.onbeforeupdate(vnode)
  },

  onbeforeupdate: function(vnode) {
    let path = m.route.param('year').padStart(4, '0')
      + '-' + m.route.param('month').padStart(2, '0')
      + '-' + m.route.param('path')
    if (this.path === path) return

    this.fetchArticle(vnode, path)
  },

  fetchArticle: function(vnode, path) {
    this.error = ''
    this.data = null
    this.path = path
    this.cacheImage = null
    this.editing = false

    api.sendRequest({
      method: 'GET',
      url: '/api/articles/' + this.path,
    })
    .then((result) => {
      this.data = result.article
      this.gotArticle(vnode)
    }, (err) => {
      this.error = err.message
    })
  },

  gotArticle: function(vnode) {
    if (!this.data) {
      return this.error = 'Article not found'
    }
    this.form.title = this.data.name
    this.form.date = new Date(this.data.publish_at)
    this.form.banner = this.data.banner_path
    this.form.metadata.speaker = this.data.content.speaker
  },

  updatevideo: function(vnode, e) {
    this.error = ''

    if (!this.form.title) this.error = lang.upload_missing_title // Title is missing
    if (!this.form.date) this.error = lang.upload_missing_date // Date is missing
    if (this.error) return false
    
    let promise = Promise.resolve()

    if (Authentication.currentUser && (typeof(this.form.banner) !== 'string' && this.cacheImage?.file !== this.form.banner)) {
      promise = api.sendRequest({
        method: 'GET',
        url: '/api/auth/uploadToken',
      })
      .then(res => {
        return api.uploadBanner(this.form.banner, res)
        .then(imageData => {
          this.cacheImage = imageData
          
          if (this.data.banner_path) {
            api.sendRequest({
              method: 'DELETE',
              url: res.delete + this.data.banner_path.slice(this.data.banner_path.lastIndexOf('/') + 1) + '?token=' + res.token,
            }).catch(err => console.error(err))
          }
  
          return res
        })
      })
    }
    
    promise.then(() => {
      return api.sendRequest({
        method: 'PUT',
        url: '/api/auth/articles/' + this.data.id,
        body: {
          name: this.form.title,
          page_id: 'null',
          path: this.form.date.toISOString().replace('T', '_').replace(/:/g, '').split('.')[0],
          content: JSON.stringify(this.form.metadata),
          publish_at: this.form.date,
          admin_id: Authentication.getTokenDecoded().user_id,
          is_featured: false,
          media: null,
          banner: this.cacheImage ? {
            filename: this.cacheImage.medium.filename,
            path: this.cacheImage.medium.path,
            type: 'image/avif',
            size: this.cacheImage.size,
            preview: {
              base64: this.cacheImage.preview.base64,
            },
          } : null,
        },
      })
    })
    .then(res => {
      this.fetchArticle(vnode, this.path)
    })
    .catch((error) => {
      console.error(error)
      this.error = lang.format(lang.article_error, error.message) // Error while saving:
    })


    return false
  },

  deletevideo: function(vnode) {
    api.sendRequest({
      method: 'GET',
      url: '/api/auth/uploadToken',
      body: this.form,
    })
    .then(res => {
      return Promise.all([
        this.data.banner_path ? api.sendRequest({
          method: 'DELETE',
          url: res.delete + this.data.banner_path.slice(this.data.banner_path.lastIndexOf('/') + 1) + '?token=' + res.token,
        }).catch(err => console.error(err)) : Promise.resolve(),
        this.data.media_path ? api.sendRequest({
          method: 'DELETE',
          url: res.delete + this.data.media_path.slice(this.data.media_path.lastIndexOf('/') + 1) + '?token=' + res.token,
        }).catch(err => console.error(err)) : Promise.resolve(),
      ])
    })
    .then(() => {
      return api.sendRequest({
        method: 'DELETE',
        url: '/api/auth/articles/' + this.data.id,
      })
    })
    .then(res => {
      videos.removeArticle(this.data.id)
      m.route.set('/')
    })
    .catch((error) => {
      if (!error) return

      this.error = lang.format(lang.delete_error, error.message) // Error while uploading:
    })
  },

  view: function(vnode) {
    return [
      api.loading && !this.data ? m('div.loading-spinner') : null,
      this.data ? [
        this.data.media_path
          ? [
              m('.player', [
                m('video', {
                  crossorigin: '',
                  controls: true,
                  preload: 'none',
                  poster: this.data.banner_path || '/assets/placeholder.avif',
                }, [
                  m('source', {
                    src: this.data.media_path
                  })
                ]),
              ]),
            ]
          : null,
        this.editing
          ? m('form.article', {
              onsubmit: this.updatevideo.bind(this, vnode),
            }, [
              m('div.form-row', [
                m('div.form-columns', [
                  m(Input, {
                    label: '',
                    type: 'file',
                    accept: 'image/*',
                    utility: 'image',
                    form: this.form,
                    formKey: 'banner',
                  }),
                ]),
                m('div.form-columns.article-name', [
                  m(Input, {
                    label: 'Title',
                    form: this.form,
                    formKey: 'title',
                  }),
                  m(Input, {
                    label: 'Date (dd.mm.yyyy)',
                    type: 'text',
                    utility: 'datetime',
                    form: this.form,
                    formKey: 'date',
                  }),
                ]),
              ]),
              m('p.separator', 'Optional'),
              m(Input, {
                label: 'Speaker',
                form: this.form.metadata,
                formKey: 'speaker',
              }),
              this.error ? m('div.full-error', this.error) : null,
              m('div.row', [
                m('input.spinner', {
                  hidden: api.loading,
                  type: 'submit',
                  value: lang.edit,
                }),
                m('div.filler', {
                  hidden: api.loading,
                }),
                api.loading ? m('div.loading-spinner') : null,
                m(HoldButton, {
                  class: 'button spinner',
                  onclick: () => this.deletevideo(vnode),
                  hidden: api.loading,
                  text: lang.delete,
                }),
              ]),
            ])
          : m('div.article', [
              m('h1', this.data.name),
              m('p', [
                lang.printdate(this.form.date),
              ]),
              m('div.table', [
                m('div.table-row', [
                  m('div.table-item', lang.article_speaker),
                  m('div.table-item', this.data.content.speaker || '...'),
                ]),
              ]),
              Authentication.currentUser?.rank >= 10
                ? m('button.button', { onclick: () => this.editing = true },lang.edit)
                : null,
            ]),
      ] : [
        this.error ? m('div.full-error', this.error) : null,
      ],
    ]
  },
}

module.exports = Article
