<script setup lang="ts">
import type {SkillInfo} from './types';
import type {ActionButton, CardPrimaryAction} from '#/components/page/CardList.vue';
import CardList from '#/components/page/CardList.vue';

import {markRaw, onMounted, ref} from 'vue';
import {useRouter} from 'vue-router';

import {Delete, Edit, Plus, Promotion, Upload} from '@element-plus/icons-vue';
import {ElMessage, ElMessageBox, ElTag} from 'element-plus';
import {tryit} from 'radash';
import HeaderSearch from '#/components/headerSearch/HeaderSearch.vue';
import PageData from '#/components/page/PageData.vue';
import PageSide from '#/components/page/PageSide.vue';
import {
  canAiResourceDelete,
  canAiResourceOffline,
  canAiResourcePublish,
  canAiResourceRepublish,
  isAiResourceApprovalPending,
  resolveAiResourceDisplayStatus,
} from '#/views/ai/shared/publish-status';

import {
  getSkillCategories,
  importSkillConfirm,
  importSkillPreview,
  submitSkillDeleteApproval,
  submitSkillOfflineApproval,
  submitSkillPublishApproval,
} from './api';

const router = useRouter();
const pageDataRef = ref();
const sideList = ref<any[]>([]);
const importInputRef = ref<HTMLInputElement>();
const selectedCategoryId = ref<string>('');
const SKILL_TAB_PAGE_KEY = '/ai/skill';

const headerButtons = [
  {
    key: 'create',
    text: '新建技能',
    icon: markRaw(Plus),
    type: 'primary',
    data: { action: 'create' },
    permission: '/api/v1/skill/save',
  },
  {
    key: 'import',
    text: '导入',
    icon: markRaw(Upload),
    type: 'default',
    data: { action: 'import' },
    permission: '/api/v1/skill/save',
  },
];

const primaryAction: CardPrimaryAction = {
  icon: Edit,
  text: '编辑',
  permission: '/api/v1/skill/update',
  onClick(row: SkillInfo) {
    router.push({
      path: `/ai/skill/detail/${row.id}`,
      query: {
        pageKey: SKILL_TAB_PAGE_KEY,
        navTitle: row.displayName || row.name || '技能详情',
      },
    });
  },
};

const actions: ActionButton[] = [
  {
    icon: Promotion,
    text: (row: SkillInfo) =>
      canAiResourceRepublish(row.displayPublishStatus, row.publishStatus)
        ? '重新发布'
        : '发布',
    permission: '/api/v1/skill/save',
    placement: 'inline',
    visible: (row: SkillInfo) =>
      canAiResourcePublish(row.displayPublishStatus, row.publishStatus) ||
      canAiResourceRepublish(row.displayPublishStatus, row.publishStatus),
    onClick: handlePublishAction,
  },
  {
    icon: Promotion,
    text: '下线',
    permission: '/api/v1/skill/save',
    placement: 'menu',
    visible: (row: SkillInfo) =>
      canAiResourceOffline(row.displayPublishStatus, row.publishStatus),
    onClick: handleOfflineAction,
  },
  {
    icon: Delete,
    text: '删除',
    permission: '/api/v1/skill/remove',
    placement: 'menu',
    tone: 'danger',
    visible: (row: SkillInfo) =>
      canAiResourceDelete(row.displayPublishStatus, row.publishStatus),
    onClick: handleDeleteAction,
  },
];

onMounted(loadCategories);

function handleSearch(keyword: string) {
  pageDataRef.value?.setQuery({
    isQueryOr: true,
    name: keyword,
    displayName: keyword,
    description: keyword,
  });
}

function handleButtonClick(payload: any) {
  if (payload?.key === 'create' || payload?.data?.action === 'create') {
    router.push({
      path: '/ai/skill/detail/new',
      query: { pageKey: SKILL_TAB_PAGE_KEY, navTitle: '新建技能' },
    });
    return;
  }
  if (payload?.key === 'import' || payload?.data?.action === 'import') {
    importInputRef.value?.click();
  }
}

function changeCategory(category: any) {
  selectedCategoryId.value = category.id || '';
  pageDataRef.value?.setQuery({ categoryId: category.id });
}

async function loadCategories() {
  const [, res] = await tryit(getSkillCategories)();
  if (res?.errorCode === 0) {
    sideList.value = [
      { id: '', categoryName: '全部分类' },
      ...(res.data || []),
    ];
  }
}

async function handleImportFile(event: Event) {
  const input = event.target as HTMLInputElement;
  const file = input.files?.[0];
  input.value = '';
  if (!file) return;
  const preview = await importSkillPreview(file);
  if (preview.errorCode !== 0) return;
  const conflictCount = preview.data?.skills?.filter((item) => item.conflict).length || 0;
  const ok = await confirmAction(
    conflictCount > 0
      ? `检测到 ${conflictCount} 个同名草稿，确认覆盖草稿并导入？`
      : '确认导入该 Skill zip？',
    conflictCount > 0 ? 'warning' : 'info',
  );
  if (!ok) return;
  const res = await importSkillConfirm(
    file,
    selectedCategoryId.value || undefined,
    conflictCount > 0,
  );
  if (res.errorCode === 0) {
    ElMessage.success('导入完成');
    pageDataRef.value?.reload?.();
  }
}

function resolvePublishStatusMeta(displayPublishStatus?: string, publishStatus?: string) {
  switch (resolveAiResourceDisplayStatus(displayPublishStatus, publishStatus)) {
    case 'DELETE_PENDING':
      return { label: '删除中', type: 'danger' as const };
    case 'OFFLINE':
      return { label: '已下线', type: 'info' as const };
    case 'OFFLINE_PENDING':
      return { label: '下线中', type: 'warning' as const };
    case 'PUBLISH_PENDING':
      return { label: '发布中', type: 'warning' as const };
    case 'PUBLISHED':
      return { label: '已发布', type: 'success' as const };
    default:
      return { label: '草稿', type: 'info' as const };
  }
}

async function confirmAction(message: string, type: 'info' | 'warning' = 'info') {
  try {
    await ElMessageBox.confirm(message, '提示', {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type,
    });
    return true;
  } catch {
    return false;
  }
}

async function handlePublishAction(row: SkillInfo) {
  if (isAiResourceApprovalPending(row.displayPublishStatus, row.publishStatus)) {
    ElMessage.warning('当前技能正在审批中');
    return;
  }
  const ok = await confirmAction(
    canAiResourceRepublish(row.displayPublishStatus, row.publishStatus)
      ? '确认提交重新发布审批？'
      : '确认提交发布审批？',
  );
  if (!ok) return;
  const res = await submitSkillPublishApproval(String(row.id));
  if (res.errorCode === 0) {
    ElMessage.success(res.message || '操作成功');
    pageDataRef.value?.reload?.();
  }
}

async function handleOfflineAction(row: SkillInfo) {
  const ok = await confirmAction('确认提交下线审批？', 'warning');
  if (!ok) return;
  const res = await submitSkillOfflineApproval(String(row.id));
  if (res.errorCode === 0) {
    ElMessage.success(res.message || '操作成功');
    pageDataRef.value?.reload?.();
  }
}

async function handleDeleteAction(row: SkillInfo) {
  const ok = await confirmAction('确认提交删除审批？', 'warning');
  if (!ok) return;
  const res = await submitSkillDeleteApproval(String(row.id));
  if (res.errorCode === 0) {
    ElMessage.success(res.message || '操作成功');
    pageDataRef.value?.reload?.();
  }
}
</script>

<template>
  <div class="skill-list-page">
    <HeaderSearch
      :buttons="headerButtons"
      @search="handleSearch"
      @button-click="handleButtonClick"
    />
    <input
      ref="importInputRef"
      class="skill-list-page__file"
      type="file"
      accept=".zip,application/zip"
      @change="handleImportFile"
    />
    <div class="skill-list-page__body">
      <PageSide
        label-key="categoryName"
        value-key="id"
        :menus="sideList"
        @change="changeCategory"
      />
      <div class="skill-list-page__content">
        <PageData
          ref="pageDataRef"
          page-url="/api/v1/skill/page"
          :page-sizes="[12, 18, 24]"
          :page-size="12"
        >
          <template #default="{ pageList }">
            <CardList
              title-field="displayName"
              desc-field="description"
              :data="pageList"
              :default-icon="''"
              :primary-action="primaryAction"
              :actions="actions"
            >
              <template #corner="{ item }">
                <ElTag
                  size="small"
                  effect="plain"
                  round
                  :type="
                    resolvePublishStatusMeta(
                      item.displayPublishStatus,
                      item.publishStatus,
                    ).type
                  "
                >
                  {{
                    resolvePublishStatusMeta(
                      item.displayPublishStatus,
                      item.publishStatus,
                    ).label
                  }}
                </ElTag>
              </template>
            </CardList>
          </template>
        </PageData>
      </div>
    </div>
  </div>
</template>

<style scoped>
.skill-list-page {
  display: flex;
  flex-direction: column;
  gap: 24px;
  height: 100%;
  padding: 24px;
}

.skill-list-page__file {
  display: none;
}

.skill-list-page__body {
  display: flex;
  flex: 1;
  gap: 24px;
  min-height: 0;
}

.skill-list-page__content {
  flex: 1;
  min-width: 0;
  height: calc(100vh - 192px);
  overflow: auto;
}
</style>

