<script setup lang="ts">
import { markRaw, ref, watch } from 'vue';
import type { TreeInstance } from 'element-plus';
import { $t } from '@/locales';
import IconMdiAccountGroupOutline from '~icons/mdi/account-group-outline';
import IconMdiArrowDecisionOutline from '~icons/mdi/arrow-decision-outline';
import IconMdiBriefcaseVariantOutline from '~icons/mdi/briefcase-variant-outline';
import IconMdiOfficeBuildingOutline from '~icons/mdi/office-building-outline';
import IconMdiSitemapOutline from '~icons/mdi/sitemap-outline';

defineOptions({ name: 'UserOrgPanel' });

interface Props {
  loading: boolean;
  treeData: Api.SystemManage.Dept[];
  currentDeptId?: number | null;
  total: number;
}

defineProps<Props>();

interface Emits {
  (e: 'refresh'): void;
  (e: 'select', dept: Api.SystemManage.Dept): void;
  (e: 'addRoot'): void;
  (e: 'addChild', dept: Api.SystemManage.Dept): void;
  (e: 'leader', dept: Api.SystemManage.Dept): void;
  (e: 'edit', dept: Api.SystemManage.Dept): void;
  (e: 'delete', dept: Api.SystemManage.Dept): void;
}

const emit = defineEmits<Emits>();

const keyword = ref('');
const treeRef = ref<TreeInstance | null>(null);

function filterNode(value: string, nodeData: Api.SystemManage.Dept) {
  if (!value.trim()) {
    return true;
  }

  return nodeData.name.toLowerCase().includes(value.trim().toLowerCase());
}

function getOrgIcon(orgType: Api.SystemManage.DeptOrgType) {
  const iconMap: Record<Api.SystemManage.DeptOrgType, object> = {
    company: markRaw(IconMdiOfficeBuildingOutline),
    dept: markRaw(IconMdiSitemapOutline),
    function: markRaw(IconMdiBriefcaseVariantOutline),
    direction: markRaw(IconMdiArrowDecisionOutline),
    team: markRaw(IconMdiAccountGroupOutline)
  };

  return iconMap[orgType];
}

watch(keyword, value => {
  treeRef.value?.filter(value);
});
</script>

<template>
  <ElCard class="card-wrapper xl:flex-1-hidden" body-class="user-org-card-body">
    <template #header>
      <div class="flex items-center justify-between gap-12px">
        <div class="flex items-center gap-8px">
          <p>{{ $t('page.system.user.orgTitle') }}</p>
          <ElTag effect="plain">{{ total }}</ElTag>
        </div>
        <div class="flex items-center gap-8px">
          <ElButton type="primary" plain size="small" @click="emit('addRoot')">
            <template #icon>
              <icon-ic-round-plus class="text-icon" />
            </template>
            {{ $t('common.add') }}
          </ElButton>
          <ElButton plain size="small" @click="emit('refresh')">
            <template #icon>
              <icon-mdi-refresh class="text-icon" />
            </template>
            {{ $t('common.refresh') }}
          </ElButton>
        </div>
      </div>
    </template>

    <div class="mb-12px">
      <ElInput v-model="keyword" clearable :placeholder="$t('page.system.user.orgFilterPlaceholder')">
        <template #prefix>
          <icon-ic-round-search class="text-icon" />
        </template>
      </ElInput>
    </div>

    <ElScrollbar v-loading="loading" class="flex-1">
      <ElTree
        ref="treeRef"
        node-key="id"
        highlight-current
        :current-node-key="currentDeptId ?? undefined"
        :data="treeData"
        default-expand-all
        :expand-on-click-node="false"
        :props="{ label: 'name', children: 'children' }"
        :filter-node-method="filterNode as any"
        @node-click="emit('select', $event)"
      >
        <template #default="{ data: nodeData }">
          <div class="group min-w-0 flex flex-1 items-center gap-8px pr-8px">
            <component :is="getOrgIcon(nodeData.orgType)" class="shrink-0 text-16px text-primary" />
            <span class="min-w-0 flex-1 truncate text-14px">{{ nodeData.name }}</span>
            <div class="flex items-center opacity-0 transition-opacity duration-200 group-hover:opacity-100">
              <ElTooltip :content="$t('page.system.user.orgLeader')">
                <ElButton link type="primary" class="user-org-action-btn" @click.stop="emit('leader', nodeData)">
                  <icon-mdi-account-tie-outline class="text-14px" />
                </ElButton>
              </ElTooltip>
              <ElTooltip :content="$t('common.add')">
                <ElButton link type="primary" class="user-org-action-btn" @click.stop="emit('addChild', nodeData)">
                  <icon-mdi-plus class="text-14px" />
                </ElButton>
              </ElTooltip>
              <ElTooltip :content="$t('common.edit')">
                <ElButton link type="primary" class="user-org-action-btn" @click.stop="emit('edit', nodeData)">
                  <icon-mdi-pencil-outline class="text-14px" />
                </ElButton>
              </ElTooltip>
              <ElPopconfirm :title="$t('common.confirmDelete')" @confirm="emit('delete', nodeData)">
                <template #reference>
                  <span class="inline-flex" @click.stop>
                    <ElTooltip :content="$t('common.delete')">
                      <ElButton link type="danger" class="user-org-action-btn">
                        <icon-mdi-delete-outline class="text-14px" />
                      </ElButton>
                    </ElTooltip>
                  </span>
                </template>
              </ElPopconfirm>
            </div>
          </div>
        </template>
      </ElTree>
    </ElScrollbar>
  </ElCard>
</template>

<style scoped lang="scss">
:deep(.user-org-card-body) {
  height: calc(100% - 56px);
  display: flex;
  flex-direction: column;
}

:deep(.user-org-action-btn) {
  padding: 2px;
  min-width: auto;
  height: auto;
  margin-left: 2px;
  line-height: 1;
}

:deep(.user-org-action-btn:first-child) {
  margin-left: 0;
}
</style>
