<template>
  <div class="flex flex-col h-full min-h-0">
    <div class="tree-header mb-2 grid grid-cols-2 place-content-between">
      <h1 class="text-lg font-semibold text-gray-900 dark:text-white">Secrets</h1>
      <div class="flex">
        <div class="flex w-full justify-end">
          <sl-dropdown>
            <sl-icon-button slot="trigger" name="plus-square" label="Add Secret"></sl-icon-button>
            <sl-menu>
              <sl-menu-item @click="createSecretDrawer = true">Create secret</sl-menu-item>
              <sl-menu-item @click="createGroupDrawer = true">
                <span v-if="currentPath">Create subgroup</span>
                <span v-else>Create group</span>
              </sl-menu-item>
            </sl-menu>
          </sl-dropdown>
        </div>
      </div>
      <div class="col-span-full">
        <!-- The search would have gone here... -->
        &nbsp;
      </div>
      <div id="secret-tree-items" class="flex flex-col h-full min-h-0 col-span-full">
        <div class="flex-1 overflow-y-auto">
          <sl-tree class="w-full" @sl-selection-change="itemSelected" v-if="treeState.secretGroups">
            <template v-if="ungrouped">
              <SecretGroupTreeItem path="ungrouped" name="Ungrouped" groupPath="ungrouped">
                <template v-for="entry in ungrouped">
                  <SecretGroupTreeEntry :name="entry.name" groupPath="ungrouped" />
                </template>
              </SecretGroupTreeItem>
            </template>
            <template v-if="secretGroups">
              <SecretGroup v-for="group in secretGroups" :group="group" />
            </template>
          </sl-tree>
        </div>
        <!-- pagination would go here -->
      </div>
    </div>
  </div>
  <Drawer label="Create Group" :open="createGroupDrawer" @hide="createGroupDrawer = false">
    <AddGroup
      :parent="currentPath"
      @submit="createGroup"
      @cancel="cancelCreateGroup"
      :key="drawerKey"
    />
  </Drawer>
  <Drawer label="Create Secret" :open="createSecretDrawer" @hide="createSecretDrawer = false">
    <SecretForm
      :key="createDrawerKey"
      :group="createSecretParent"
      @submit="createSecret"
      @cancel="createSecretDrawer = false"
    />
  </Drawer>
</template>
<script setup lang="ts">
import type { SshecretObject } from '@/api/types'
import type { SecretCreate } from '@/client'
import { computed, ref, reactive, onMounted, watch } from 'vue'
import { useTreeState } from '@/store/useTreeState'
import { useAlertsStore } from '@/store/useAlertsStore'
import { SshecretAdmin } from '@/client'
import { SshecretObjectType } from '@/api/types'
import SecretGroup from '@/components/secrets/SecretGroup.vue'
import SecretGroupTreeItem from '@/components/secrets/SecretGroupTreeItem.vue'
import SecretGroupTreeEntry from '@/components/secrets/SecretGroupTreeEntry.vue'
import AddGroup from '@/components/secrets/AddGroup.vue'
import SecretForm from '@/components/secrets/SecretForm.vue'
import Drawer from '@/components/common/Drawer.vue'

const treeState = useTreeState()
const alerts = useAlertsStore()

const ungrouped = computed(() => treeState.secretGroups.ungrouped)
const secretGroups = computed(() => treeState.secretGroups.groups)

const groupSelected = computed(() => {
  if (!treeState.selected) {
    return false
  }
  if (treesState.selected.objectType === SshecretObject.SecretGroup) {
    return true
  }
  return false
})

const drawerKey = ref(0)
const createDrawerKey = ref(0)
const createGroupDrawer = ref<boolean>(false)
const createSecretDrawer = ref<boolean>(false)

function cancelCreateGroup() {
  createGroupDrawer.value = false
  drawerKey.value += 1
}

const currentPath = computed(() => {
  if (treeState.selected && treeState.selected.objectType === SshecretObjectType.SecretGroup) {
    return treeState.selected.id
  }
  return ''
})

const createSecretParent = computed(() => {
  if (treeState.selected && treeState.selected.objectType === SshecretObjectType.SecretGroup) {
    return treeState.selected.id
  }
  return null
})

async function loadGroups() {
  await treeState.getSecretGroups()
}

const drawerKeyName = computed(() => `${currentPath.value}_${drawerKey.value}`)

async function itemSelected(event: Event) {
  if (event.detail.selection.length == 0) {
    treeState.unselect()
  } else {
    const el = event.detail.selection[0] as HTMLElement
    const childType = el.dataset.type
    if (childType === 'secret') {
      const secretName = el.dataset.name
      treeState.selectSecret(secretName, null)
    } else if (childType === 'group') {
      const groupPath = el.dataset.groupPath
      if (groupPath === 'ungrouped') {
        treeState.unselect()
      } else {
        treeState.selectGroup(groupPath)
      }
    }
  }
}

async function createGroup(path: string) {
  // Create a group
  console.log('Submit called')
  const response = await SshecretAdmin.addSecretGroupApiV1SecretsGroupsPost({
    body: {
      name: path,
    },
  })
  if (response.status === 200) {
    console.log('Success. Group created.')
    alerts.showAlert('Group created', 'success')
    createGroupDrawer.value = false
    drawerKey.value += 1

    await loadGroups()
  } else {
    console.error(response)
    alerts.showAlert('Group creation failed', 'error')
  }
}

async function createSecret(secretCreate: SecretCreate) {
  console.log('Creating secret')
  const response = await SshecretAdmin.addSecretApiV1SecretsPost({
    body: secretCreate,
  })
  if (response.status == 200) {
    alerts.showAlert('Secret created', 'success')
    // We can close the drawer now.
    createSecretDrawer.value = false
    createDrawerKey.value += 1

    await loadGroups()
    // Also update all the clients affected
    for (const clientId in secretCreate.clients) {
      console.log('Refreshing client: ', clientId)
      await treeState.refreshClient(clientId)
    }

    treeState.selectSecret(secretCreate.name)
  } else {
    console.log(response)
    alerts.showAlert('Secret creation failed', 'error')
  }
}

watch(
  () => treeState.secretGroupRevision,
  () => {
    treeState.getSecretGroups()
  },
)

onMounted(loadGroups)
</script>
