var { h, computed, when, map, send } = require('mutant')
var nest = require('depnest')
var extend = require('xtend')
var moment = require('moment')

exports.needs = nest({
  'message.html.markdown': 'first',
  'message.html.layout': 'first',
  'message.html.decorate': 'reduce',
  'message.async.publish': 'first',
  'keys.sync.id': 'first',
  'about.html.image': 'first',
  'about.obs.latestValue': 'first',
  'about.obs.groupedValues': 'first',
  'about.obs.valueFrom': 'first',
  'about.obs.name': 'first',
  'contact.obs.following': 'first',
  'blob.sync.url': 'first',
  'gathering.sheet.edit': 'first'
})

exports.gives = nest('message.html', {
  canRender: true,
  render: true
})

exports.create = function (api) {
  var following = null

  return nest('message.html', {
    canRender: isRenderable,
    render: function (msg, opts) {
      if (!isRenderable(msg)) return

      var yourId = api.keys.sync.id()
      var hidden = api.about.obs.valueFrom(msg.key, 'hidden', yourId)
      var image = api.about.obs.latestValue(msg.key, 'image')
      var title = api.about.obs.latestValue(msg.key, 'title')
      var description = api.about.obs.latestValue(msg.key, 'description')
      var location = api.about.obs.latestValue(msg.key, 'location')
      var startDateTime = api.about.obs.latestValue(msg.key, 'startDateTime')
      // var endDateTime = api.about.obs.latestValue(msg.key, 'endDateTime')
      var attendees = computed([api.about.obs.groupedValues(msg.key, 'attendee')], getAttendees)
      if (!following) {
        following = api.contact.obs.following(yourId)
      }

      var imageUrl = computed(image, (id) => api.blob.sync.url(id))
      var imageId = computed(image, (link) => (link && link.link) || link)
      var content = h('GatheringCard', [
        h('div.title', [
          h('a', {
            href: msg.key
          }, title),
          h('button', {
            'ev-click': send(api.gathering.sheet.edit, msg.key)
          }, 'Edit Details')
        ]),
        h('div.time', computed(startDateTime, formatTime)),
        when(image, h('a.image', {
          href: imageId,
          style: {
            'background-image': computed(imageUrl, (url) => `url(${url})`)
          }
        })),
        h('div.attending', [
          h('div.title', ['Attendees', ' (', computed(attendees, (x) => x.length), ')']),
          h('div.attendees', [
            map(attendees, (attendee) => {
              return h('a.attendee', {
                href: attendee,
                title: nameAndFollowWarning(attendee)
              }, api.about.html.image(attendee))
            })
          ]),
          h('div.actions', [
            h('button -attend', {
              'ev-click': send(publishAttending, msg.key)
            }, `Attending`),
            h('button -attend', {
              'ev-click': send(publishNotAttending, msg.key)
            }, `Can't Attend`)
          ])
        ]),
        h('div.location', markdown(location)),
        when(description, h('div.description', markdown(description)))
      ])

      var element = api.message.html.layout(msg, extend({
        content,
        miniContent: 'Added a gathering',
        layout: 'mini'
      }, opts))

      // hide if no title set or hidden
      var visible = computed([title, hidden], (title, hidden) => {
        return title && !hidden
      })

      return when(visible, api.message.html.decorate(element, {
        msg
      }))
    }
  })

  function publishAttending (id) {
    var yourId = api.keys.sync.id()

    // publish with confirm
    api.message.async.publish({
      type: 'about',
      about: id,
      attendee: {
        link: yourId
      }
    })
  }

  function publishNotAttending (id) {
    var yourId = api.keys.sync.id()

    // publish with confirm
    api.message.async.publish({
      type: 'about',
      about: id,
      attendee: {
        link: yourId,
        remove: true
      }
    })
  }

  function nameAndFollowWarning (id) {
    var yourId = api.keys.sync.id()
    return computed([api.about.obs.name(id), id, following], function nameAndFollowWarning (name, id, following) {
      if (id === yourId) {
        return `${name} (you)`
      } else if (following.includes(id)) {
        return `${name}`
      } else {
        return `${name} (not following)`
      }
    })
  }

  function markdown (obs) {
    return computed(obs, (text) => {
      if (typeof text === 'string') return api.message.html.markdown(text)
    })
  }
}

function formatTime (time) {
  if (time && time.epoch) {
    return moment(time.epoch).format('LLLL')
  }
}

function getAttendees (lookup) {
  return Object.keys(lookup)
}

function isRenderable (msg) {
  return (msg.value.content.type === 'gathering') ? true : undefined
}

@@ -2037,26 +2037,63 @@
 teTime, 
-formatTime
+(time) =%3E %60$%7BformatTime(time)%7D (your timezone)%60
 )),%0A    

Add (your timezone) to gatherings