<!--
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the 'License');
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an 'AS IS' BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
  import { AccountRole, getCurrentAccount, Timestamp } from '@hcengineering/core'
  import { copyTextToClipboard, LiveQuery } from '@hcengineering/presentation'
  import {
    Button,
    EditBox,
    getCurrentLocation,
    Label,
    Loading,
    locationToUrl,
    MiniToggle,
    ticker
  } from '@hcengineering/ui'
  import { getInviteLink } from '../utils'
  import { createEventDispatcher } from 'svelte'
  import login from '../plugin'
  import InviteWorkspace from './icons/InviteWorkspace.svelte'
  import { loginId } from '@hcengineering/login'
  import setting from '@hcengineering/setting'

  const dispatch = createEventDispatcher()

  const query = new LiveQuery()

  $: query.query(setting.class.InviteSettings, {}, (set) => {
    if (set !== undefined && set.length > 0) {
      expHours = set[0].expirationTime
      emailMask = set[0].emailMask
      limit = set[0].limit
    } else {
      expHours = 48
      limit = -1
    }
    if (limit === -1) noLimit = true
    defaultValues = {
      expirationTime: expHours,
      emailMask,
      limit
    }
  })

  function setToDefault () {
    expHours = defaultValues.expirationTime
    emailMask = defaultValues.emailMask
    limit = defaultValues.limit
  }

  async function getLink (expHours: number, mask: string, limit: number): Promise<void> {
    loading = true
    const inviteId = await getInviteLink(expHours, mask, limit)
    const loc = getCurrentLocation()
    loc.path[0] = loginId
    loc.path[1] = 'join'
    loc.path.length = 2
    loc.query = {
      inviteId
    }
    loc.fragment = undefined

    const url = locationToUrl(loc)
    link = document.location.origin + url
    loading = false
  }

  let copiedTime: Timestamp | undefined
  let copied = false
  $: {
    if (copiedTime) {
      if (copied && $ticker - copiedTime > 1000) {
        copied = false
      }
    }
  }
  function copy (): void {
    if (link === undefined) return
    copyTextToClipboard(link)
    copied = true
    copiedTime = Date.now()
  }

  let expHours: number | undefined = undefined
  let emailMask: string = ''
  let limit: number | undefined = undefined
  let useDefault: boolean | undefined = true
  let noLimit: boolean = false
  const isOwnerOrMaintainer: boolean = getCurrentAccount().role > AccountRole.Maintainer
  let defaultValues = {
    expirationTime: undefined,
    emailMask: '',
    limit: undefined
  }

  let link: string | undefined
  let loading = false
</script>

<div class="antiPopup popup">
  <div class="flex-between fs-title mb-2">
    <Label label={login.string.InviteDescription} />
    <InviteWorkspace size="large" />
  </div>
  {#if isOwnerOrMaintainer}
    <div class="mb-2">
      <MiniToggle
        bind:on={useDefault}
        label={login.string.UseWorkspaceInviteSettings}
        on:click={() => setToDefault()}
      />
      {#if !useDefault}
        <div class="mt-2">
          <EditBox
            label={login.string.LinkValidHours}
            bind:value={expHours}
            format={'number'}
            on:keypress={() => (link = undefined)}
            disabled={useDefault || !isOwnerOrMaintainer}
          />
        </div>
        <div class="mt-2">
          <EditBox
            label={login.string.EmailMask}
            bind:value={emailMask}
            format={'string'}
            on:keypress={() => (link = undefined)}
            disabled={useDefault || !isOwnerOrMaintainer}
          />
        </div>

        <div class="mt-2">
          <MiniToggle bind:on={noLimit} label={login.string.NoLimit} on:change={() => noLimit && (limit = -1)} />
        </div>
        {#if !noLimit}
          <div class="mt-2">
            <EditBox
              label={login.string.InviteLimit}
              bind:value={limit}
              format={'number'}
              on:keypress={() => (link = undefined)}
              disabled={useDefault || !isOwnerOrMaintainer}
            />
          </div>
        {/if}
      {/if}
    </div>
  {/if}
  {#if loading}
    <Loading />
  {:else if link !== undefined}
    <!-- svelte-ignore a11y-click-events-have-key-events -->
    <div class="over-underline link" on:click={copy}>{link}</div>
    <div class="buttons flex">
      <Button label={copied ? login.string.Copied : login.string.Copy} size={'medium'} on:click={copy} />
      <Button
        label={login.string.Close}
        size={'medium'}
        kind={'primary'}
        on:click={() => {
          dispatch('close')
        }}
      />
    </div>
  {:else}
    <div class="buttons flex">
      <Button
        label={login.string.GetLink}
        size={'medium'}
        kind={'primary'}
        on:click={() => {
          ;(limit > 0 || noLimit) && getLink(expHours, emailMask, limit)
        }}
      />
    </div>
  {/if}
</div>

<style lang="scss">
  .popup {
    display: flex;
    flex-direction: column;
    padding: 1rem;
    color: var(--theme-caption-color);
    background-color: var(--theme-button-bg-hovered);
    border: 1px solid var(--theme-button-border-enabled);
    border-radius: 0.75rem;
    min-width: 30rem;
    filter: drop-shadow(0 1.5rem 4rem rgba(0, 0, 0, 0.35));

    .link {
      margin-top: 2rem;
      margin-bottom: 2rem;
      overflow-wrap: break-word;
    }

    .buttons {
      justify-content: space-around;
      align-items: center;
    }
  }
</style>
