<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 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 { Class, Ref } from '@hcengineering/core'
  import { AttributeEditor, getClient } from '@hcengineering/presentation'
  import type { DoneState, KanbanTemplate, KanbanTemplateSpace, State } from '@hcengineering/task'
  import {
    CircleButton,
    IconAdd,
    IconMoreH,
    Label,
    showPopup,
    getPlatformColor,
    eventToHTMLElement,
    Component
  } from '@hcengineering/ui'
  import { createEventDispatcher } from 'svelte'
  import { ColorsPopup } from '@hcengineering/view-resources'
  import Circles from './Circles.svelte'
  import StatusesPopup from './StatusesPopup.svelte'
  import task from '../../plugin'
  import Won from '../icons/Won.svelte'
  import Lost from '../icons/Lost.svelte'

  export let template: KanbanTemplate | undefined = undefined
  export let space: KanbanTemplateSpace | undefined = undefined
  export let states: State[] = []
  export let wonStates: DoneState[] = []
  export let lostStates: DoneState[] = []

  const dispatch = createEventDispatcher()
  const client = getClient()

  const elements: HTMLElement[] = []
  let selected: number | undefined
  let dragState: Ref<State>

  function dragswap (ev: MouseEvent, i: number): boolean {
    const s = selected as number
    if (i < s) {
      return ev.offsetY < elements[i].offsetHeight / 2
    } else if (i > s) {
      return ev.offsetY > elements[i].offsetHeight / 2
    }
    return false
  }

  function dragover (ev: MouseEvent, i: number) {
    const s = selected as number
    if (dragswap(ev, i)) {
      ;[states[i], states[s]] = [states[s], states[i]]
      selected = i
    }
  }

  async function onMove (to: number) {
    dispatch('move', {
      stateID: dragState,
      position: to
    })
  }

  const onColorChange =
    (state: State) =>
      async (color: number | undefined): Promise<void> => {
        if (color === undefined) {
          return
        }

        await client.updateDoc(state._class, state.space, state._id, { color })
      }

  async function onAdd (_class: Ref<Class<State | DoneState>>) {
    dispatch('add', _class)
  }
</script>

{#if space?.editor}
  <Component is={space.editor} props={{ template }} />
{/if}
<div class="flex-no-shrink flex-between trans-title uppercase">
  <Label label={task.string.ActiveStates} />
  <CircleButton
    icon={IconAdd}
    size={'medium'}
    on:click={() => {
      onAdd(task.class.State)
    }}
  />
</div>
<div class="mt-3">
  {#each states as state, i}
    {#if state}
      <div
        bind:this={elements[i]}
        class="flex-between states"
        draggable={true}
        on:dragover|preventDefault={(ev) => {
          dragover(ev, i)
        }}
        on:drop|preventDefault={() => {
          onMove(i)
        }}
        on:dragstart={() => {
          selected = i
          dragState = states[i]._id
        }}
        on:dragend={() => {
          selected = undefined
        }}
      >
        <div class="bar"><Circles /></div>
        <div
          class="color"
          style="background-color: {getPlatformColor(state.color)}"
          on:click={() => {
            showPopup(ColorsPopup, {}, elements[i], onColorChange(state))
          }}
        />
        <div class="flex-grow caption-color">
          <AttributeEditor maxWidth={'20rem'} _class={state._class} object={state} key="title" />
        </div>
        {#if states.length > 1}
          <div
            class="tool hover-trans"
            on:click={(ev) => {
              showPopup(
                StatusesPopup,
                { onDelete: () => dispatch('delete', { state }) },
                eventToHTMLElement(ev),
                () => {}
              )
            }}
          >
            <IconMoreH size={'medium'} />
          </div>
        {/if}
      </div>
    {/if}
  {/each}
</div>
<div class="mt-9">
  <div class="flex-no-shrink flex-between trans-title uppercase">
    <Label label={task.string.DoneStatesWon} />
    <CircleButton
      icon={IconAdd}
      size={'medium'}
      on:click={() => {
        onAdd(task.class.WonState)
      }}
    />
  </div>
  <div class="mt-4">
    {#each wonStates as state}
      {#if state}
        <div class="states flex-row-center">
          <div class="bar" />
          <div class="mr-2">
            <Won size={'medium'} />
          </div>
          <div class="flex-grow caption-color">
            <AttributeEditor maxWidth={'13rem'} _class={state._class} object={state} key="title" />
          </div>
          {#if wonStates.length > 1}
            <div
              class="tool hover-trans"
              on:click={(ev) => {
                showPopup(
                  StatusesPopup,
                  { onDelete: () => dispatch('delete', { state }) },
                  eventToHTMLElement(ev),
                  () => {}
                )
              }}
            >
              <IconMoreH size={'medium'} />
            </div>
          {/if}
        </div>
      {/if}
    {/each}
  </div>
</div>
<div class="mt-9">
  <div class="flex-no-shrink flex-between trans-title uppercase">
    <Label label={task.string.DoneStatesLost} />
    <CircleButton
      icon={IconAdd}
      size={'medium'}
      on:click={() => {
        onAdd(task.class.LostState)
      }}
    />
  </div>
  <div class="mt-4 mb-10">
    {#each lostStates as state}
      {#if state}
        <div class="states flex-row-center">
          <div class="bar" />
          <div class="mr-2">
            <Lost size={'medium'} />
          </div>
          <div class="flex-grow caption-color">
            <AttributeEditor maxWidth={'13rem'} _class={state._class} object={state} key="title" />
          </div>
          {#if lostStates.length > 1}
            <div
              class="tool hover-trans"
              on:click={(ev) => {
                showPopup(
                  StatusesPopup,
                  { onDelete: () => dispatch('delete', { state }) },
                  eventToHTMLElement(ev),
                  () => {}
                )
              }}
            >
              <IconMoreH size={'medium'} />
            </div>
          {/if}
        </div>
      {/if}
    {/each}
  </div>
</div>

<style lang="scss">
  .states {
    padding: 0.5rem 1rem;
    color: var(--caption-color);
    background-color: var(--button-bg-color);
    border: 1px solid var(--button-border-color);
    border-radius: 0.5rem;
    user-select: none;

    .bar {
      margin-right: 0.375rem;
      width: 0.375rem;
      height: 1rem;
      opacity: 0.4;
      cursor: grabbing;
    }
    .color {
      margin-right: 0.75rem;
      width: 1rem;
      height: 1rem;
      border-radius: 0.25rem;
      cursor: pointer;
    }
    .tool {
      margin-left: 1rem;
    }
  }
  .states + .states {
    margin-top: 0.5rem;
  }
</style>
