<article class="status-article {{getClasses(originalStatus, timelineType, isStatusInOwnThread)}}"
         tabindex="0"
         delegate-key="{{delegateKey}}"
         focus-key="{{delegateKey}}"
         aria-posinset="{{index}}"
         aria-setsize="{{length}}"
         aria-label="{{ariaLabel}}"
         on:recalculateHeight>
  {{#if showHeader}}
    <StatusHeader :notification :status :isStatusInNotification :timelineType />
  {{/if}}
  <StatusAuthorName status="{{originalStatus}}" :isStatusInOwnThread :isStatusInNotification />
  <StatusAuthorHandle status="{{originalStatus}}" :isStatusInNotification />
  {{#if !isStatusInOwnThread}}
    <StatusRelativeDate status="{{originalStatus}}" :isStatusInNotification />
  {{/if}}
  <StatusSidebar status="{{originalStatus}}" :isStatusInOwnThread />
  {{#if originalStatus.spoiler_text}}
    <StatusSpoiler status="{{originalStatus}}" :isStatusInOwnThread :contextualStatusId :isStatusInNotification
                   on:recalculateHeight />
  {{/if}}
  {{#if !originalStatus.spoiler_text || spoilerShown}}
    <StatusContent status="{{originalStatus}}" :isStatusInOwnThread :isStatusInNotification />
  {{/if}}
  {{#if originalStatus.media_attachments && originalStatus.media_attachments.length}}
    <StatusMediaAttachments status="{{originalStatus}}" :timelineType :timelineValue />
  {{/if}}
  {{#if isStatusInOwnThread}}
  <StatusDetails status="{{originalStatus}}" />
  {{/if}}
  <StatusToolbar status="{{originalStatus}}" :isStatusInOwnThread />
</article>

<style>
  .status-article {
    cursor: pointer;
    max-width: calc(100vw - 40px);
    padding: 10px 20px;
    display: grid;
    grid-template-areas:
        "....... header       header        header"
        "sidebar author-name  author-handle relative-date"
        "sidebar spoiler      spoiler       spoiler"
        "sidebar spoiler-btn  spoiler-btn   spoiler-btn"
        "sidebar content      content       content"
        "media   media        media         media"
        "....... toolbar      toolbar       toolbar";
    grid-template-columns: min-content minmax(0, max-content) 1fr min-content;
  }

  .status-article.status-in-timeline {
    width: 560px;
    border-bottom: 1px solid var(--main-border);
  }

  .status-article.status-direct {
    background-color: var(--status-direct-background);
  }

  .status-article.status-in-own-thread {
    grid-template-areas:
      "sidebar     author-name"
      "sidebar     author-handle"
      "spoiler     spoiler"
      "spoiler-btn spoiler-btn"
      "content     content"
      "media       media"
      "details     details"
      "toolbar     toolbar";
    grid-template-columns: min-content 1fr;
  }

  @media (max-width: 767px) {
    .status-article {
      padding: 10px 10px;
      max-width: calc(100vw - 20px);
    }
    .status-article.status-in-timeline {
      width: 580px;
    }
  }
</style>
<script>
  import StatusSidebar from './StatusSidebar.html'
  import StatusHeader from './StatusHeader.html'
  import StatusAuthorName from './StatusAuthorName.html'
  import StatusAuthorHandle from './StatusAuthorHandle.html'
  import StatusRelativeDate from './StatusRelativeDate.html'
  import StatusDetails from './StatusDetails.html'
  import StatusToolbar from './StatusToolbar.html'
  import StatusMediaAttachments from './StatusMediaAttachments.html'
  import StatusContent from './StatusContent.html'
  import StatusSpoiler from './StatusSpoiler.html'
  import { store } from '../../_store/store'
  import { goto } from 'sapper/runtime.js'
  import { registerClickDelegate, unregisterClickDelegate } from '../../_utils/delegate'
  import { classname } from '../../_utils/classname'

  export default {
    oncreate() {
      let delegateKey = this.get('delegateKey')
      if (!this.get('isStatusInOwnThread')) {
        // the whole <article> is clickable in this case
        registerClickDelegate(delegateKey, (e) => this.onClickOrKeydown(e))
      }
    },
    ondestroy() {
      let delegateKey = this.get('delegateKey')
      if (!this.get('isStatusInOwnThread')) {
        unregisterClickDelegate(delegateKey)
      }
    },
    components: {
      StatusSidebar,
      StatusHeader,
      StatusAuthorName,
      StatusAuthorHandle,
      StatusRelativeDate,
      StatusDetails,
      StatusToolbar,
      StatusMediaAttachments,
      StatusContent,
      StatusSpoiler
    },
    store: () => store,
    helpers: {
      getClasses(originalStatus, timelineType, isStatusInOwnThread) {
        return classname(
          originalStatus.visibility === 'direct' && 'status-direct',
          timelineType !== 'search' && 'status-in-timeline',
          isStatusInOwnThread && 'status-in-own-thread'
        )
      }
    },
    methods: {
      onClickOrKeydown(e) {
        let { type, keyCode } = e
        let { localName, parentElement } = e.target

        if ((type === 'click' || (type === 'keydown' && keyCode === 13)) &&
            localName !== 'a' &&
            localName !== 'button' &&
            parentElement.localName !== 'a' &&
            parentElement.localName !== 'button' &&
            parentElement.parentElement.localName !== 'a' &&
            parentElement.parentElement.localName !== 'button') {
          e.preventDefault()
          e.stopPropagation()
          goto(`/statuses/${this.get('statusId')}`)
        }
      }
    },
    computed: {
      originalStatus: (status) => status.reblog ? status.reblog : status,
      statusId: (originalStatus) => originalStatus.id,
      delegateKey: (statusId) => `status-${statusId}`,
      contextualStatusId: ($currentInstance, timelineType, timelineValue, status, notification) => {
        return `${$currentInstance}/${timelineType}/${timelineValue}/${notification ? notification.id : ''}/${status.id}`
      },
      originalAccount: (originalStatus) => originalStatus.account,
      isStatusInOwnThread: (timelineType, timelineValue, statusId) => {
        return (timelineType === 'status' || timelineType === 'reply') && timelineValue === statusId
      },
      isStatusInNotification: (status, notification) => notification && notification.status && notification.type !== 'mention' && notification.status.id === status.id,
      spoilerShown: ($spoilersShown, contextualStatusId) => !!$spoilersShown[contextualStatusId],
      visibility: (originalStatus) => originalStatus.visibility,
      ariaLabel: (originalAccount, visibility) => {
        return (visibility === 'direct' ? 'Direct message' : 'Status') +
          ` by ${originalAccount.display_name || originalAccount.username}`
      },
      showHeader: (notification, status, timelineType) => {
        return (notification && (notification.type === 'reblog' || notification.type === 'favourite'))
          || status.reblog
          || timelineType === 'pinned'
      }
    }
  }
</script>