<script setup lang="ts">
import type { PluginListRouteState } from './plugin-route-state';

import type {
  ActionButton,
  CardPrimaryAction,
} from '#/components/page/CardList.vue';

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

import { EasyFlowFormModal } from '@easyflow/common-ui';
import { $t } from '@easyflow/locales';

import { Delete, Edit, Plus } from '@element-plus/icons-vue';
import {
  ElForm,
  ElFormItem,
  ElInput,
  ElMessage,
  ElMessageBox,
  ElTag,
} from 'element-plus';

import { api } from '#/api/request';
import defaultPluginIcon from '#/assets/ai/plugin/defaultPluginIcon.png';
import HeaderSearch from '#/components/headerSearch/HeaderSearch.vue';
import PluginToolIcon from '#/components/icons/PluginToolIcon.vue';
import CardPage from '#/components/page/CardList.vue';
import PageData from '#/components/page/PageData.vue';
import PageSide from '#/components/page/PageSide.vue';
import {
  buildListRouteFullPath,
  watchListRouteState,
} from '#/composables/useListRouteState';
import { withListReturnTo } from '#/router/list-return-context';
import { createLazyComponentController } from '#/utils/lazy-component';

import { buildPluginPageQueryParams } from './plugin-query';
import {
  mergePluginListRouteQuery,
  parsePluginListRouteState,
  pluginListRouteSchema,
} from './plugin-route-state';

const route = useRoute();
const router = useRouter();
const initialListState = parsePluginListRouteState(route.query);

interface PluginCategory {
  id: string;
  name: string;
}

interface PluginRecord {
  id: string;
  [key: string]: unknown;
}

interface HeaderActionEvent {
  key?: string;
}

interface CategoryFormData {
  id?: string;
  name: string;
}

interface AddPluginModalInstance {
  openDialog: (row: Record<string, unknown>) => void;
}

const {
  component: AddPluginModalComponent,
  componentRef: aiPluginModalRef,
  ensureInstance: ensureAddPluginModal,
  loading: pluginModalLoading,
} = createLazyComponentController<AddPluginModalInstance>(
  () => import('#/views/ai/plugin/AddPluginModal.vue'),
);

async function openPluginDialog(row: Record<string, unknown>) {
  try {
    const modal = await ensureAddPluginModal();
    modal.openDialog(row);
  } catch (error) {
    console.error('Failed to load plugin modal:', error);
    ElMessage.error($t('message.getDataError'));
  }
}

function resolveNavTitle(item: PluginRecord) {
  return (item.title as string) || (item.name as string) || '';
}

function openPluginTools(item: PluginRecord) {
  router.push({
    path: '/ai/plugin/tools',
    query: {
      id: item.id,
      pageKey: '/ai/plugin',
      navTitle: resolveNavTitle(item),
      ...withListReturnTo(currentListFullPath()),
    },
  });
}

const primaryAction: CardPrimaryAction = {
  icon: PluginToolIcon,
  text: $t('plugin.button.tools'),
  permission: '/api/v1/plugin/save',
  onClick(item) {
    openPluginTools(item);
  },
};

const actions: ActionButton[] = [
  {
    icon: Edit,
    text: $t('button.edit'),
    permission: '/api/v1/plugin/save',
    placement: 'inline',
    onClick(item) {
      void openPluginDialog(item);
    },
  },
  {
    icon: Delete,
    text: $t('button.delete'),
    tone: 'danger',
    permission: '/api/v1/plugin/remove',
    placement: 'menu',
    onClick(item) {
      handleDelete(item);
    },
  },
];
const pluginTypeTagMap = {
  1: $t('plugin.typeHttp'),
  2: $t('plugin.typeWorkflow'),
};
const categoryList = ref<PluginCategory[]>([]);
const selectedCategoryId = ref(initialListState.categoryId);
const searchKeyword = ref(initialListState.keyword.trim());
const currentPageNumber = ref(initialListState.pageNumber);
const currentPageSize = ref(initialListState.pageSize);
const suppressInitialCategoryChange = ref(true);
const initialQueryParams = buildPluginPageQueryParams(
  initialListState.categoryId,
  initialListState.keyword,
);
const controlBtns = [
  {
    icon: Edit,
    label: $t('button.edit'),
    onClick(row: PluginCategory) {
      formData.value.name = row.name;
      formData.value.id = row.id;
      isEdit.value = true;
      dialogVisible.value = true;
    },
  },
  {
    type: 'danger',
    icon: Delete,
    label: $t('button.delete'),
    onClick(row: PluginCategory) {
      handleDeleteCategory(row);
    },
  },
];
const footerButton = {
  icon: Plus,
  label: $t('button.add'),
  onClick() {
    dialogVisible.value = true;
    isEdit.value = false;
  },
};
const getPluginCategoryList = async () => {
  return api.get('/api/v1/pluginCategory/visibleList').then((res) => {
    if (res.errorCode === 0) {
      const serverCategories = Array.isArray(res.data)
        ? (res.data as PluginCategory[])
        : [];
      categoryList.value = [
        { id: '0', name: $t('common.allCategories') },
        ...serverCategories,
      ];
      if (
        selectedCategoryId.value !== '0' &&
        !serverCategories.some(
          (category) =>
            String(category.id) === String(selectedCategoryId.value),
        )
      ) {
        suppressInitialCategoryChange.value = false;
        selectedCategoryId.value = '0';
        applyFilters();
      }
    }
  });
};
onMounted(() => {
  getPluginCategoryList();
});
const handleDelete = (item: PluginRecord) => {
  ElMessageBox.confirm($t('message.deleteAlert'), $t('message.noticeTitle'), {
    confirmButtonText: $t('message.ok'),
    cancelButtonText: $t('message.cancel'),
    type: 'warning',
  })
    .then(() => {
      api.post('/api/v1/plugin/plugin/remove', { id: item.id }).then((res) => {
        if (res.errorCode === 0) {
          ElMessage.success($t('message.deleteOkMessage'));
          pageDataRef.value?.reload?.();
        }
      });
    })
    .catch(() => {});
};

const pageDataRef = ref();
watchListRouteState(route, pluginListRouteSchema, (state) => {
  if (String(state.categoryId) !== String(selectedCategoryId.value)) {
    suppressInitialCategoryChange.value = true;
  }
  selectedCategoryId.value = state.categoryId;
  searchKeyword.value = state.keyword.trim();
  currentPageNumber.value = state.pageNumber;
  currentPageSize.value = state.pageSize;
  pageDataRef.value?.restoreState?.({
    pageNumber: state.pageNumber,
    pageSize: state.pageSize,
    queryParams: buildPluginPageQueryParams(state.categoryId, state.keyword),
  });
});
const headerButtons = [
  {
    key: 'add',
    text: $t('plugin.button.addPlugin'),
    icon: Plus,
    type: 'primary',
    data: { action: 'add' },
  },
];
const dialogVisible = ref(false); // 弹窗显隐
const isEdit = ref(false); // 是否为编辑模式
const formData = ref<CategoryFormData>({ name: '', id: '' });

const handleSubmit = () => {
  // 触发对应事件，传递表单数据
  if (isEdit.value) {
    handleEditCategory(formData.value);
  } else {
    handleAddCategory(formData.value);
  }
  // 提交后关闭弹窗
  dialogVisible.value = false;
};
const handleButtonClick = (event: HeaderActionEvent, _item: unknown) => {
  switch (event.key) {
    case 'add': {
      void openPluginDialog({});
      break;
    }
  }
};

function applyFilters() {
  pageDataRef.value?.setQuery(
    buildPluginPageQueryParams(selectedCategoryId.value, searchKeyword.value),
  );
}

function currentListState(): PluginListRouteState {
  const pageState = pageDataRef.value?.getPageState?.();
  return {
    categoryId: String(selectedCategoryId.value || '0'),
    keyword: searchKeyword.value,
    pageNumber: pageState?.pageNumber ?? currentPageNumber.value,
    pageSize: pageState?.pageSize ?? currentPageSize.value,
  };
}

function currentListFullPath() {
  return buildListRouteFullPath(
    router,
    route.query,
    currentListState(),
    pluginListRouteSchema,
  );
}

function syncListRouteState() {
  const target = {
    path: '/ai/plugin',
    query: mergePluginListRouteQuery(route.query, currentListState()),
  };
  if (router.resolve(target).fullPath !== route.fullPath) {
    void router.replace(target);
  }
}

function handlePageStateChange(state: {
  pageNumber: number;
  pageSize: number;
}) {
  currentPageNumber.value = state.pageNumber;
  currentPageSize.value = state.pageSize;
  syncListRouteState();
}

const handleSearch = (params?: string) => {
  searchKeyword.value = params?.trim() ?? '';
  applyFilters();
};
const reloadCurrentList = () => {
  pageDataRef.value?.reload?.();
};
const handleEditCategory = (params: CategoryFormData) => {
  api
    .post('/api/v1/pluginCategory/update', {
      id: params.id,
      name: params.name,
    })
    .then((res) => {
      if (res.errorCode === 0) {
        getPluginCategoryList();
        ElMessage.success($t('message.updateOkMessage'));
      }
    });
};
const handleAddCategory = (params: CategoryFormData) => {
  api.post('/api/v1/pluginCategory/save', { name: params.name }).then((res) => {
    if (res.errorCode === 0) {
      getPluginCategoryList();
      ElMessage.success($t('message.saveOkMessage'));
    }
  });
};
const handleDeleteCategory = (params: PluginCategory) => {
  api
    .get(`/api/v1/pluginCategory/doRemoveCategory?id=${params.id}`)
    .then((res) => {
      if (res.errorCode === 0) {
        getPluginCategoryList();
        ElMessage.success($t('message.deleteOkMessage'));
      }
    });
};
const handleClickCategory = (item: PluginCategory) => {
  if (
    suppressInitialCategoryChange.value &&
    String(item.id) === String(selectedCategoryId.value)
  ) {
    suppressInitialCategoryChange.value = false;
    selectedCategoryId.value = item.id;
    return;
  }
  suppressInitialCategoryChange.value = false;
  selectedCategoryId.value = item.id;
  applyFilters();
};
</script>

<template>
  <div v-loading="pluginModalLoading" class="knowledge-container">
    <div class="knowledge-header">
      <HeaderSearch
        :buttons="headerButtons"
        :initial-value="searchKeyword"
        :search-placeholder="$t('plugin.searchUsers')"
        @search="handleSearch"
        @button-click="handleButtonClick"
      />
    </div>
    <div class="plugin-content-container">
      <div class="category-panel-container">
        <PageSide
          label-key="name"
          value-key="id"
          :menus="categoryList"
          :control-btns="controlBtns"
          :footer-button="footerButton"
          :default-selected="selectedCategoryId"
          @change="handleClickCategory"
        />
      </div>

      <div class="plugin-content-data-container h-full overflow-auto">
        <PageData
          ref="pageDataRef"
          page-url="/api/v1/plugin/pageByCategory"
          :page-size="initialListState.pageSize"
          :page-sizes="[12, 24, 36, 48]"
          :initial-page-number="initialListState.pageNumber"
          :initial-query-params="initialQueryParams"
          @state-change="handlePageStateChange"
        >
          <template #default="{ pageList }">
            <CardPage
              title-field="title"
              icon-field="icon"
              desc-field="description"
              tag-field="type"
              :tag-map="pluginTypeTagMap"
              :data="pageList"
              :primary-action="primaryAction"
              :actions="actions"
              :default-icon="defaultPluginIcon"
              density="compact"
              meta-layout="compact"
            >
              <template #corner="{ item }">
                <ElTag
                  v-if="item.type === 2 && item.available === false"
                  type="danger"
                  effect="light"
                  round
                >
                  {{
                    item.reasonMessage || $t('plugin.workflowPluginUnavailable')
                  }}
                </ElTag>
              </template>
            </CardPage>
          </template>
        </PageData>
      </div>
    </div>
    <component
      :is="AddPluginModalComponent"
      v-if="AddPluginModalComponent"
      ref="aiPluginModalRef"
      @reload="reloadCurrentList"
    />
    <EasyFlowFormModal
      :title="isEdit ? `${$t('button.edit')}` : `${$t('button.add')}`"
      v-model:open="dialogVisible"
      :confirm-text="$t('button.confirm')"
      width="500px"
      @confirm="handleSubmit"
    >
      <ElForm
        :model="formData"
        status-icon
        label-position="top"
        class="easyflow-modal-form easyflow-modal-form--compact"
      >
        <ElFormItem>
          <ElInput v-model.trim="formData.name" />
        </ElFormItem>
      </ElForm>
    </EasyFlowFormModal>
  </div>
</template>

<style scoped>
.knowledge-container {
  width: 100%;
  padding: 24px;
  margin: 0 auto;
}

h1 {
  margin-bottom: 30px;
  color: #303133;
  text-align: center;
}

.plugin-content-container {
  display: flex;
  gap: 24px;
  height: calc(100vh - 161px);
  padding-top: 24px;
}

.plugin-content-data-container {
  /* padding: 20px; */

  /* background-color: var(--el-bg-color); */
  width: 100%;
  border-top-right-radius: var(--el-border-radius-base);
  border-bottom-right-radius: var(--el-border-radius-base);
}
</style>
