<script lang="ts">
  import attachment, { Attachment } from '@hcengineering/attachment'
  import chunter, { ChunterMessage } from '@hcengineering/chunter'
  import contact, { Employee } from '@hcengineering/contact'
  import core, { DocumentQuery, Ref, SortingOrder, toIdMap } from '@hcengineering/core'
  import { createQuery, getClient } from '@hcengineering/presentation'
  import { Label, Scroller, SearchEdit } from '@hcengineering/ui'
  import { FilterBar } from '@hcengineering/view-resources'
  import MessageComponent from './Message.svelte'
  import plugin from '../plugin'
  import { openMessageFromSpecial } from '../utils'

  export let withHeader: boolean = true

  export let search: string = ''

  let searchQuery: DocumentQuery<ChunterMessage> = { $search: search }

  function updateSearchQuery (search: string): void {
    searchQuery = { $search: search }
  }

  $: updateSearchQuery(search)

  const client = getClient()
  export let filterClass = chunter.class.ChunterMessage
  let messages: ChunterMessage[] = []

  let resultQuery: DocumentQuery<ChunterMessage> = { ...searchQuery }

  async function updateMessages (resultQuery: DocumentQuery<ChunterMessage>) {
    messages = await client.findAll(
      filterClass,
      {
        ...resultQuery
      },
      {
        sort: { createOn: SortingOrder.Descending },
        limit: 100,
        lookup: {
          _id: { attachments: attachment.class.Attachment },
          createBy: core.class.Account
        }
      }
    )
  }

  $: updateMessages(resultQuery)

  let employees: Map<Ref<Employee>, Employee> = new Map<Ref<Employee>, Employee>()
  const employeeQuery = createQuery()

  employeeQuery.query(contact.class.Employee, {}, (res) => (employees = toIdMap(res)), {
    lookup: { _id: { statuses: contact.class.Status } }
  })

  const pinnedQuery = createQuery()
  const pinnedIds: Ref<ChunterMessage>[] = []

  pinnedQuery.query(
    chunter.class.Channel,
    {},
    (res) => {
      res.forEach((ch) => {
        if (ch.pinned) {
          pinnedIds.push(...ch.pinned)
        }
      })
    },
    {}
  )
  let savedMessagesIds: Ref<ChunterMessage>[] = []
  let savedAttachmentsIds: Ref<Attachment>[] = []

  const savedMessagesQuery = createQuery()
  const savedAttachmentsQuery = createQuery()

  savedMessagesQuery.query(chunter.class.SavedMessages, {}, (res) => {
    savedMessagesIds = res.map((r) => r.attachedTo)
  })

  savedAttachmentsQuery.query(attachment.class.SavedAttachments, {}, (res) => {
    savedAttachmentsIds = res.map((r) => r.attachedTo)
  })
</script>

{#if withHeader}
  <div class="ac-header full divide">
    <div class="ac-header__wrap-title">
      <span class="ac-header__title"><Label label={plugin.string.MessagesBrowser} /></span>
    </div>
    <SearchEdit
      value={search}
      on:change={() => {
        updateSearchQuery(search)
        updateMessages(resultQuery)
      }}
    />
  </div>
{/if}
<FilterBar _class={filterClass} query={searchQuery} on:change={(e) => (resultQuery = e.detail)} />
{#if messages.length > 0}
  <Scroller>
    {#each messages as message}
      <div on:click={() => openMessageFromSpecial(message)}>
        <MessageComponent
          {message}
          {employees}
          on:openThread
          isPinned={pinnedIds.includes(message._id)}
          isSaved={savedMessagesIds.includes(message._id)}
          {savedAttachmentsIds}
        />
      </div>
    {/each}
  </Scroller>
{:else}
  <div class="flex-center h-full text-lg">
    <Label label={plugin.string.NoResults} />
  </div>
{/if}
