<script setup lang="ts">
/* cspell:ignore tryit */
import type {AgentInfo} 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} from '@element-plus/icons-vue';
import {ElMessage, ElMessageBox, ElTag} from 'element-plus';
import {tryit} from 'radash';

import defaultAvatar from '#/assets/ai/bot/defaultBotAvatar.png';
import HeaderSearch from '#/components/headerSearch/HeaderSearch.vue';
import PageData from '#/components/page/PageData.vue';
import PageSide from '#/components/page/PageSide.vue';
import {$t} from '#/locales';
import {
  canAiResourceDelete,
  canAiResourceOffline,
  canAiResourcePublish,
  canAiResourceRepublish,
  isAiResourceApprovalPending,
  resolveAiResourceDisplayStatus,
} from '#/views/ai/shared/publish-status';

import {
  getAgentCategories,
  submitAgentDeleteApproval,
  submitAgentOfflineApproval,
  submitAgentPublishApproval,
} from './api';

const router = useRouter();
const pageDataRef = ref();
const sideList = ref<any[]>([]);
const AGENT_TAB_PAGE_KEY = '/ai/agents';
const DEFAULT_AGENT_TITLE = '未命名智能体';

const headerButtons = [
  {
    key: 'create',
    text: '创建智能体',
    icon: markRaw(Plus),
    type: 'primary',
    data: { action: 'create' },
    permission: '/api/v1/agent/save',
  },
];

const primaryAction: CardPrimaryAction = {
  icon: Edit,
  text: '编排',
  permission: '/api/v1/agent/update',
  onClick(row: AgentInfo) {
    router.push({
      path: `/ai/agents/designer/${row.id}`,
      query: {
        pageKey: AGENT_TAB_PAGE_KEY,
        navTitle: resolveNavTitle(row),
      },
    });
  },
};

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

onMounted(() => {
  loadCategories();
});

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

function handleButtonClick(payload: any) {
  if (payload?.key === 'create' || payload?.data?.action === 'create') {
    router.push({
      path: '/ai/agents/designer/new',
      query: {
        pageKey: AGENT_TAB_PAGE_KEY,
        navTitle: DEFAULT_AGENT_TITLE,
      },
    });
  }
}

function resolveNavTitle(row: AgentInfo) {
  return String(row.name || '').trim() || DEFAULT_AGENT_TITLE;
}

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

async function loadCategories() {
  const [, res] = await tryit(getAgentCategories)();
  if (res?.errorCode === 0) {
    sideList.value = [
      { id: '', categoryName: $t('common.allCategories') },
      ...(res.data || []),
    ];
  }
}

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, $t('message.noticeTitle'), {
      confirmButtonText: $t('button.confirm'),
      cancelButtonText: $t('button.cancel'),
      type,
    });
    return true;
  } catch {
    return false;
  }
}

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

async function handleOfflineAction(row: AgentInfo) {
  if (
    isAiResourceApprovalPending(row.displayPublishStatus, row.publishStatus)
  ) {
    ElMessage.warning('当前智能体正在审批中');
    return;
  }
  const ok = await confirmAction('确认提交下线审批？', 'warning');
  if (!ok) return;
  const res = await submitAgentOfflineApproval(String(row.id));
  if (res.errorCode === 0) {
    ElMessage.success(res.message || $t('message.saveOkMessage'));
    pageDataRef.value?.reload?.();
  }
}

async function handleDeleteAction(row: AgentInfo) {
  if (
    isAiResourceApprovalPending(row.displayPublishStatus, row.publishStatus)
  ) {
    ElMessage.warning('当前智能体正在审批中');
    return;
  }
  const ok = await confirmAction('确认提交删除审批？', 'warning');
  if (!ok) return;
  const res = await submitAgentDeleteApproval(String(row.id));
  if (res.errorCode === 0) {
    ElMessage.success(res.message || $t('message.saveOkMessage'));
    pageDataRef.value?.reload?.();
  }
}
</script>

<template>
  <div class="agent-list-page">
    <HeaderSearch
      :buttons="headerButtons"
      @search="handleSearch"
      @button-click="handleButtonClick"
    />
    <div class="agent-list-page__body">
      <PageSide
        label-key="categoryName"
        value-key="id"
        :menus="sideList"
        @change="changeCategory"
      />
      <div class="agent-list-page__content">
        <PageData
          ref="pageDataRef"
          page-url="/api/v1/agent/page"
          :page-sizes="[12, 18, 24]"
          :page-size="12"
        >
          <template #default="{ pageList }">
            <CardList
              title-field="name"
              icon-field="avatar"
              :default-icon="defaultAvatar"
              :data="pageList"
              :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>
.agent-list-page {
  display: flex;
  flex-direction: column;
  gap: 24px;
  height: 100%;
  padding: 24px;
}

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

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