import type { TableColumnType } from 'antdv-next';

import type { PropType } from 'vue';

import type { WordpressBlogApi } from '#/api/blog';
import type {
  KtTableApi,
  KtTableButton,
  KtTableRowAction,
} from '#/components/ktTable';

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

import { Page, useVbenModal } from '@vben/common-ui';
import { Plus } from '@vben/icons';

import { message } from 'antdv-next';

import { useVbenForm } from '#/adapter/form';
import {
  createCategory,
  createTag,
  deleteCategory,
  deleteTag,
  getCategoryList,
  getTagList,
  updateCategory,
  updateTag,
} from '#/api/blog';
import { KtTable, useKtTable } from '#/components/ktTable';

import { setBlogArticleFilters } from './use-article-filters';

type TermSearchValues = {
  search?: string;
};

const AKtTable = KtTable as any;

export default defineComponent({
  name: 'BlogTermManagement',
  props: {
    kind: {
      required: true,
      type: String as PropType<'category' | 'tag'>,
    },
    title: {
      required: true,
      type: String,
    },
  },
  setup(props) {
    const route = useRoute();
    const router = useRouter();

    const editingId = ref<string>();
    const tableRows = ref<WordpressBlogApi.Term[]>([]);
    const parentOptions = computed(() =>
      tableRows.value
        .filter((item) => item.id !== editingId.value)
        .map((item) => ({ label: item.name, value: item.id })),
    );

    const [TermForm, termFormApi] = useVbenForm({
      commonConfig: {
        labelClass: 'w-24',
      },
      layout: 'horizontal',
      schema: [
        {
          component: 'Input',
          componentProps: () => ({
            placeholder: `请输入${props.title}名称`,
          }),
          fieldName: 'name',
          label: '名称',
          rules: 'required',
        },
        {
          component: 'Input',
          componentProps: {
            placeholder: '可选，默认由名称生成',
          },
          fieldName: 'slug',
          label: '别名',
        },
        {
          component: 'Select',
          componentProps: () => ({
            allowClear: true,
            options: parentOptions.value,
            placeholder: '选择父级分类',
          }),
          dependencies: {
            if: () => props.kind === 'category',
            triggerFields: ['name'],
          },
          fieldName: 'parent',
          label: '父级分类',
        },
        {
          component: 'Textarea',
          componentProps: {
            autoSize: { maxRows: 6, minRows: 3 },
            placeholder: '可选',
          },
          fieldName: 'description',
          label: '描述',
        },
      ],
      showDefaultActions: false,
      wrapperClass: 'grid-cols-1',
    });

    const modalTitle = computed(() =>
      editingId.value ? `编辑${props.title}` : `新建${props.title}`,
    );
    const [TermModal, termModalApi] = useVbenModal({
      class: 'w-[620px]',
      fullscreenButton: false,
      async onConfirm() {
        await submitTerm();
      },
      onOpenChange(isOpen: boolean) {
        if (!isOpen) return;
        const { values } = termModalApi.getData<{
          values?: WordpressBlogApi.TermBody;
        }>();
        void resetTermForm(values || getTermFormDefaults());
      },
    });
    const permissionModule = computed(() =>
      props.kind === 'category' ? 'Blog:Category' : 'Blog:Tag',
    );
    const columns = computed<Array<TableColumnType<WordpressBlogApi.Term>>>(
      () => [
        { dataIndex: 'name', key: 'name', title: '名称', width: 220 },
        { dataIndex: 'slug', key: 'slug', title: '别名', width: 180 },
        { dataIndex: 'count', key: 'count', title: '文章数', width: 100 },
        {
          dataIndex: 'description',
          key: 'description',
          title: '描述',
          width: 300,
        },
      ],
    );
    const api: KtTableApi<WordpressBlogApi.Term, TermSearchValues> = {
      list: async (params) => {
        const requestParams = {
          hide_empty: false,
          pageNo: params.pageNo,
          pageSize: params.pageSize,
          search: params.search,
        };

        return props.kind === 'category'
          ? await getCategoryList(requestParams)
          : await getTagList(requestParams);
      },
    };
    const buttons = computed<
      Array<KtTableButton<WordpressBlogApi.Term, TermSearchValues>>
    >(() => [
      {
        icon: <Plus class="kt-table__button-icon" />,
        key: 'create',
        label: `新建${props.title}`,
        onClick: openCreate,
        permissionCodes: [`${permissionModule.value}:Create`],
        type: 'primary',
      },
    ]);
    const rowActions = computed<
      Array<KtTableRowAction<WordpressBlogApi.Term, TermSearchValues>>
    >(() => [
      {
        key: 'articles',
        label: '查看文章',
        onClick: openRelatedArticles,
        permissionCodes: ['Blog:Article:List'],
      },
      {
        key: 'edit',
        label: '编辑',
        onClick: openEdit,
        permissionCodes: [`${permissionModule.value}:Edit`],
      },
      {
        confirm: (row) =>
          `确认删除${props.title}「${row.name}」吗？本操作不会删除已关联文章。`,
        danger: true,
        key: 'delete',
        label: '删除',
        onClick: async (row, context) => {
          await (props.kind === 'category'
            ? deleteCategory(row.id)
            : deleteTag(row.id));
          message.success(`${props.title}删除成功`);
          await context.reload();
        },
        permissionCodes: [`${permissionModule.value}:Delete`],
      },
    ]);

    const [registerTable, tableApi] = useKtTable<
      WordpressBlogApi.Term,
      TermSearchValues
    >({
      afterFetch: (result) => {
        tableRows.value = Array.isArray(result)
          ? result
          : result.list || result.records || result.items || [];
        return result;
      },
      api,
      buttons: buttons.value,
      columns: columns.value,
      formOptions: {
        schema: [
          {
            component: 'Input',
            componentProps: {
              allowClear: true,
              placeholder: `搜索${props.title}名称`,
            },
            fieldName: 'search',
            label: '关键词',
          },
        ],
      },
      immediate: false,
      rowActions: rowActions.value,
      tableTitle: props.title,
    });

    function getRouteSearch() {
      const value = route.query.search;
      return Array.isArray(value) ? value[0] || '' : value || '';
    }

    function syncTableProps() {
      tableApi.setProps({
        buttons: buttons.value,
        columns: columns.value,
        formOptions: {
          schema: [
            {
              component: 'Input',
              componentProps: {
                allowClear: true,
                placeholder: `搜索${props.title}名称`,
              },
              fieldName: 'search',
              label: '关键词',
            },
          ],
        },
        rowActions: rowActions.value,
        tableTitle: props.title,
      });
    }

    function getTermFormDefaults(): WordpressBlogApi.TermBody {
      return {
        description: '',
        name: '',
        parent: undefined,
        slug: '',
      };
    }

    async function resetTermForm(values: WordpressBlogApi.TermBody) {
      await termFormApi.resetForm();
      await termFormApi.setValues(values);
      await termFormApi.resetValidate();
    }

    function openCreate() {
      editingId.value = undefined;
      termModalApi.setData({ values: getTermFormDefaults() }).open();
    }

    function openEdit(row: WordpressBlogApi.Term) {
      editingId.value = row.id;
      termModalApi
        .setData({
          values: {
            description: row.description || '',
            id: row.id,
            name: row.name,
            parent: row.parent || undefined,
            slug: row.slug || '',
          },
        })
        .open();
    }

    async function submitTerm() {
      const { valid } = await termFormApi.validate();
      if (!valid) return;

      const values = await termFormApi.getValues<WordpressBlogApi.TermBody>();
      const name = values.name?.trim();
      if (!name) {
        message.warning(`请填写${props.title}名称`);
        return;
      }

      termModalApi.lock();
      try {
        const payload = {
          ...values,
          id: editingId.value,
          name,
        };
        if (props.kind === 'category') {
          await (editingId.value
            ? updateCategory(payload)
            : createCategory(payload));
        } else {
          await (editingId.value ? updateTag(payload) : createTag(payload));
        }
        message.success(`${props.title}保存成功`);
        await termModalApi.close();
        await tableApi.reload();
      } finally {
        termModalApi.unlock();
      }
    }

    function openRelatedArticles(row: WordpressBlogApi.Term) {
      setBlogArticleFilters(
        props.kind === 'category'
          ? { categories: [row.name] }
          : { tags: [row.name] },
      );
      router.push({
        name: 'BlogArticle',
      });
    }

    async function reloadWithRouteSearch() {
      syncTableProps();
      await tableApi.setSearchValues({ search: getRouteSearch() });
      await tableApi.reload();
    }

    watch(
      () => props.kind,
      () => {
        reloadWithRouteSearch();
      },
    );

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

    return () => (
      <Page autoContentHeight>
        <AKtTable
          onRegister={registerTable}
          v-slots={{
            bodyCell: ({ column, record }: any) => {
              const term = record as WordpressBlogApi.Term;

              if (column.key === 'description') {
                return (
                  <span class="line-clamp-2">{term.description || '-'}</span>
                );
              }

              return undefined;
            },
          }}
        />

        <TermModal title={modalTitle.value}>
          <TermForm class="mx-2" />
        </TermModal>
      </Page>
    );
  },
});
