<template>
  <f7-page @page:beforein="onPageBeforeIn" @page:beforeout="onPageBeforeOut" ref="addondetails" class="page-addon-details">
    <f7-navbar :transparent="true" back-link="Back" class="addon-details-nav">
      <f7-nav-title v-if="addon">
        {{ addon.label }}
      </f7-nav-title>
    </f7-navbar>
    <f7-block class="block-narrow addon-details" v-if="ready && addon">
      <f7-row>
        <f7-col class="margin-left">
          <div class="addon-header">
            <f7-link class="logo-container" :href="docLinkUrl" external target="_blank">
              <f7-icon v-show="!logoLoaded" size="100" color="gray" :f7="addonIcon" style="opacity: 0.2; position: absolute;" />
              <img v-if="!logoError" class="logo lazy" :style="{ visibility: logoLoaded ? 'visible': 'hidden' }" ref="logo" :data-src="imageUrl">
            </f7-link>
            <div class="addon-header-content">
              <div class="addon-header-title">
                {{ addon.label }}
              </div>
              <div v-if="addon.verifiedAuthor" class="addon-header-subtitle">
                {{ addon.author }}
                <f7-icon :color="$f7.data.themeOptions.dark === 'dark' ? 'white' : 'blue'" f7="checkmark_seal_fill" />
              </div>
              <div v-else-if="addon.properties && addon.properties.views" class="addon-header-subtitle">
                <addon-stats-line :addon="addon" :iconSize="15" />
              </div>
              <div class="addon-header-actions">
                <f7-preloader v-if="isPending(addon)" color="blue" />
                <f7-button v-else-if="addon.installed" class="install-button" text="Remove" color="red" round small fill @click="openAddonPopup" />
                <f7-button v-else class="install-button" :text="installableAddon(addon) ? 'Install' : 'Add'" color="blue" round small fill @click="openAddonPopup" />
                <f7-link v-if="!isPending(addon) && bindingInfo && bindingInfo.configDescriptionURI" icon-f7="gears" tooltip="Configure Binding" color="blue" :href="'/settings/addons/' + bindingInfo.id + '/config'" round small />
              </div>
            </div>
          </div>
        </f7-col>
      </f7-row>
      <f7-row>
        <f7-col>
          <f7-block strong class="addon-description" v-if="descriptionReady">
            <div v-show="descriptionExpanded" v-html="parsedDescription" class="addon-description-text" />
            <div v-show="!descriptionExpanded" v-html="addonDescription" class="addon-description-text" />
            <div v-show="!descriptionExpanded" class="text-align-right">
              <f7-link @click="descriptionExpanded = true">
                more
              </f7-link>
            </div>
          </f7-block>
          <f7-block v-else class="skeleton-text skeleton-effect-blink">
            <p>
              Lorem ipsum dolor sit amet, an labore inermis est.
              Mel ut dicant tamquam commune, duo id accumsan eleifend tractatos, ius purto vitae fabulas cu.
              Te his vide omnis qualisque, in duo soluta persecuti instructior. Ex dicit detraxit voluptaria est.
              Aperiri reformidans comprehensam in vis.
            </p>
            <p>
              Quo quas rebum dicta ad, in erant eruditi vim.
              Mel no primis everti voluptatum, id utamur voluptatibus mea.
              Nam deseruisse expetendis cotidieque at, vis oratio utroque cu.
              Eu duo quod fuisset, ne fabulas hendrerit argumentum pro.
              Errem dictas his ea, eos interesset efficiantur ei.
            </p>
          </f7-block>
        </f7-col>
      </f7-row>
      <f7-row>
        <f7-col>
          <f7-block-title class="margin-left margin-bottom-half" medium>
            Information
          </f7-block-title>
          <addon-info-table v-if="ready && addon" :addon="addon" />
        </f7-col>
      </f7-row>
    </f7-block>
    <addon-details-sheet
      v-if="ready"
      :addon-id="realAddonId"
      :service-id="serviceId"
      :no-details="true"
      :opened="addonPopupOpened"
      @closed="addonPopupOpened = false"
      @install="installAddon"
      @uninstall="uninstallAddon" />
  </f7-page>
</template>

<style lang="stylus">
.theme-filled .addon-details-nav.navbar:not(.navbar-transparent-visible) .link
  color var(--f7-theme-color)
  transition color 0.3s
.theme-filled .addon-details-nav.navbar.navbar-transparent-visible .link
  color var(--f7-navbar-link-color)
  transition color 0.3s
.addon-details
  width calc(100%)
  .addon-header
    display flex
    align-items stretch
    .logo-container
      display flex
      justify-content center
      align-items center
      width 118px
      height 118px
      border-radius 22%
      margin-right var(--f7-block-padding-horizontal)
      flex-shrink 0
      background white
      border 1px solid rgba(0, 0, 0, 0.1)
      .logo
        max-width 100px
        max-height 100px
    @media (min-width 768px)
      .logo-container
        width 191px
        height 191px
        .logo
          max-width 165px
          max-height 165px
    .addon-header-content
      display flex
      flex-direction column
      width calc(100% - 2*var(--f7-block-padding-horizontal))
      flex-shrink 10
      min-width 0
      line-height 27px
      .addon-header-title
        font-size 22px
        font-weight 600
      @media (min-width 768px)
        .addon-header-title
          font-size 27px
          line-height normal
      .addon-header-subtitle
        font-size 16px
        font-weight 600
        color var(--f7-list-item-after-text-color)
        i
          font-size 16px
      @media (min-width 768px)
        .addon-header-author
          font-size 20px
          i
            font-size 20px
    .addon-header-actions
      display flex
      justify-content space-between
      align-items center
      margin-top auto
      margin-bottom auto
      margin-right 15px
      .install-button
        --f7-button-text-transform uppercase
        padding-left 15px
        padding-right 15px
        font-size 16px
  .addon-description
    --f7-block-strong-bg-color transparent
    width calc(100%)
    --f7-theme-color var(--f7-color-blue)
  .addon-description-text
    overflow-x clip
    .emoji
      height 1rem
    .lightbox-wrapper .meta
      display none
    pre
      overflow auto
      width calc(100% - 2*var(--f7-block-padding-horizontal-half))
      max-height 70vh
      color var(--f7-block-footer-text-color)
    img
      max-width calc(100%)
      height auto
      &[alt="logo"]
        display none
      &.lazy:not(.lazy-loaded)
        opacity 0
</style>

<script>
import AddonStoreMixin from './addon-store-mixin'
import { AddonIcons, ContentTypes, Formats } from '@/assets/addon-store'
import AddonStatsLine from '@/components/addons/addon-stats-line.vue'
import AddonInfoTable from '@/components/addons/addon-info-table.vue'

export default {
  mixins: [AddonStoreMixin],
  components: {
    AddonStatsLine,
    AddonInfoTable
  },
  props: ['addonId'],
  data () {
    return {
      addon: null,
      ready: false,
      logoLoaded: false,
      logoError: false,
      addonIcon: null,
      descriptionReady: false,
      parsedDescription: '',
      descriptionExpanded: false,
      bindingInfo: null
    }
  },
  computed: {
    realAddonId () {
      if (!this.addon) return null
      return (this.addon.id.indexOf(':') > 0) ? this.addon.id.substring(this.addon.id.indexOf(':') + 1) : this.addon.id
    },
    serviceId () {
      if (!this.addon) return null
      return (this.addon.id.indexOf(':') > 0) ? this.addon.id.substring(0, this.addon.id.indexOf(':')) : undefined
    },
    imageUrl () {
      if (!this.addon) return null
      if (this.addon.imageLink) return this.addon.imageLink.replace(/^\/\//, 'https://')
      let docsBranch = 'final'
      if (this.$store.state.runtimeInfo.buildString === 'Release Build') docsBranch = 'final-stable'
      return `https://raw.githubusercontent.com/openhab/openhab-docs/${docsBranch}/images/addons/${this.addon.id.substring(this.addon.id.indexOf('-') + 1)}.png`
    },
    addonDescription () {
      if (!this.descriptionReady) return null
      if (!this.addon) return null
      if (this.addon.description) return this.addon.description
      if (this.parsedDescription) {
        const firstHeading = this.parsedDescription.match(/<h\d/m)
        if (firstHeading && firstHeading.index > 0) return this.parsedDescription.substring(0, firstHeading.index)
        return this.parsedDescription
      }
      return 'No description found'
    },
    docLinkUrl () {
      if (!this.addon) return ''
      if (this.serviceId && this.serviceId !== 'karaf' && this.addon.link) return this.addon.link
      if (this.addon.id.indexOf('-') > 0) {
        let url = `https://${this.$store.state.runtimeInfo.buildString === 'Release Build' ? 'www' : 'next'}.openhab.org` +
          `/addons/${this.addon.type.replace('misc', 'integrations').replace('binding', 'bindings').replace('transformation', 'transformations')}` +
          `/${this.addon.id.substring(this.addon.id.indexOf('-') + 1)}`
        return url
      }
      return ''
    }
  },
  methods: {
    onPageBeforeIn () {
      this.ready = false
      this.load()
    },
    onPageBeforeOut () {
      this.stopEventSource()
    },
    load () {
      this.stopEventSource()
      let addonId = this.addonId
      let serviceId = null
      if (addonId.indexOf(':') > 0) {
        serviceId = addonId.substring(0, addonId.indexOf(':'))
        addonId = addonId.substring(addonId.indexOf(':') + 1)
      }
      this.bindingInfo = null
      this.$oh.api.get('/rest/addons/' + addonId + (serviceId ? '?serviceId=' + serviceId : '')).then((data) => {
        this.resetPending()
        this.$set(this, 'addon', data)
        this.addonIcon = AddonIcons[this.addon.type]
        this.ready = true
        this.processDescription()
        this.startEventSource()

        setTimeout(() => {
          this.$$(this.$refs.logo).once('lazy:loaded', (e) => {
            console.log(this.addon.id + ' logo lazy loaded')
            this.logoLoaded = true
          })
          this.$$(this.$refs.logo).once('lazy:error', (e) => {
            this.logoError = true
          })
          this.$f7.lazy.create('.page-addon-details')
        })

        if (this.addon.type === 'binding' && this.addonId.indexOf('binding-') === 0 && this.addon.installed) {
          this.$oh.api.get('/rest/bindings').then(data2 => {
            this.bindingInfo = data2.find(b => b.id === this.addonId.replace('binding-', '')) || {}
          })
        }
      })
    },
    processDescription () {
      if (!this.addon.description && this.addon.author === 'openHAB') {
        // assuming the add-on is an official one (distribution), try to fetch the documentation from GitHub
        let docsBranch = 'final'
        if (this.$store.state.runtimeInfo.buildString === 'Release Build') docsBranch = 'final-stable'
        let addonTypeFolder = '_addons_' + this.addon.type
        if (this.addon.type === 'misc') addonTypeFolder = '_addons_io'
        if (this.addon.type !== 'automation') addonTypeFolder += 's'
        let addonId = this.addon.id.substring(this.addon.id.indexOf('-') + 1)
        let docUrl = (this.$store.state.runtimeInfo.buildString === 'Release Build') ? 'https://www.openhab.org' : 'https://next.openhab.org'
        docUrl += `/addons/${this.addon.type}/${addonId}`
        let docSrcUrl = `https://raw.githubusercontent.com/openhab/openhab-docs/${docsBranch}/${addonTypeFolder}/${addonId}`

        fetch(docSrcUrl + '/readme.md').then((readme) => {
          readme.text().then((text) => {
            import('marked').then((marked) => {
              const frontmatterSeparators = [...text.matchAll(/^---$/gm)]
              let body

              if (frontmatterSeparators.length !== 2) {
                body = '<p>The description is not available for this add-on.</p><h3>Debug Information</h3><blockquote>' + text + '</blockquote>'
              } else {
                const frontmatter = text.substring(4, frontmatterSeparators[1].index)
                body = marked.default(text.substring(frontmatterSeparators[1].index + 4))

                // perform a few replaces on HTML body for Markdown readmes on GitHub
                body = body.replace(/<p>{% include base.html %}<\/p>\n/gm, '')
                body = body.replace(/<h1 .*$/gm, '')
                body = body.replace(/<pre>/gm, '<div class="block block-strong no-padding"><pre class="padding-half">')
                body = body.replace(/<\/pre>/gm, '</pre></div>')
                body = body.replace(/<table>/gm, '<div class="data-table"><table>')
                body = body.replace(/<\/table>/gm, '</table></div>')
                body = body.replace(/<a href="http/gm, '<a class="external" target="_blank" href="http')
                body = body.replace(/<img src="doc/gm, '<img class="lazy lazy-fade-in" data-src="' + docSrcUrl + '/doc')
                body = body.replace(/<img src="contrib/gm, '<img class="lazy lazy-fade-in" data-src="' + docSrcUrl + '/contrib')
              }

              this.parsedDescription = body
              this.descriptionReady = true
              setTimeout(() => { this.$f7.lazy.create('.addon-description-text') })
            })
          })
        }).catch((err) => {
          this.parsedDescription = '<p>The description is unavailable for this add-on.</p><h3>Debug Information</h3><blockquote>' + err + '</blockquote>'
          this.descriptionReady = true
          setTimeout(() => { this.$f7.lazy.create('.addon-description-text') })
        })
      } else {
        // perform a few replaces for Discourse "cooked" HTML
        let body = this.addon.detailedDescription
        if (!body) return
        body = body.replace(/<pre>/gm, '<div class="block block-strong no-padding"><pre class="padding-half">')
        body = body.replace(/<\/pre>/gm, '</pre></div>')
        body = body.replace(/<table>/gm, '<div class="data-table"><table>')
        body = body.replace(/<\/table>/gm, '</table></div>')
        body = body.replace(/<a class="lightbox" href="/gm, '<a class="external" target="_blank" href="')
        body = body.replace(/<a href="http/gm, '<a class="external" target="_blank" href="http')
        body = body.replace(/<img src="\/\/community-openhab-org/gm, '<img class="lazy lazy-fade-in" data-src="//community-openhab-org')
        this.parsedDescription = body
        this.descriptionReady = true
        setTimeout(() => { this.$f7.lazy.create('.addon-description-text') })
      }
    }
  }
}
</script>
