import { flushPromises, mount } from '@vue/test-utils';

import { beforeEach, describe, expect, it, vi } from 'vitest';

import SkillCategoryFormDialog from './SkillCategoryFormDialog.vue';

const apiMocks = vi.hoisted(() => ({
  getSkillCategoryTree: vi.fn(),
  saveSkillCategory: vi.fn(),
  updateSkillCategory: vi.fn(),
}));

vi.mock('./api', () => apiMocks);
vi.mock('@easyflow/common-ui', async () => {
  const { defineComponent, h } = await import('vue');
  return {
    EasyFlowFormModal: defineComponent({
      props: {
        open: Boolean,
        submitting: Boolean,
        title: {
          default: '',
          type: String,
        },
      },
      emits: ['confirm', 'update:open'],
      setup(props, { emit, slots }) {
        return () =>
          h('section', { class: 'form-modal-stub' }, [
            h('h2', props.title),
            slots.default?.(),
            h(
              'button',
              {
                class: 'form-modal-confirm',
                disabled: props.submitting,
                onClick: () => emit('confirm'),
                type: 'button',
              },
              '保存',
            ),
          ]);
      },
    }),
  };
});

describe('skill category form dialog', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    apiMocks.getSkillCategoryTree.mockResolvedValue({
      data: [
        {
          categoryName: '研发',
          id: 1,
          levelNo: 1,
          status: 1,
          children: [
            {
              categoryName: '平台',
              id: 2,
              levelNo: 2,
              parentId: 1,
              status: 1,
            },
          ],
        },
      ],
      errorCode: 0,
    });
    apiMocks.saveSkillCategory.mockResolvedValue({ data: {}, errorCode: 0 });
    apiMocks.updateSkillCategory.mockResolvedValue({
      data: {},
      errorCode: 0,
    });
  });

  it('creates a root category with the compact shared form modal', async () => {
    const wrapper = mount(SkillCategoryFormDialog, {
      props: { modelValue: true },
    });
    await flushPromises();

    expect(wrapper.get('h2').text()).toBe('添加分类');
    await wrapper.get('input').setValue('内容审核');
    await wrapper.get('.form-modal-confirm').trigger('click');
    await flushPromises();

    expect(apiMocks.saveSkillCategory).toHaveBeenCalledWith(
      expect.objectContaining({
        categoryName: '内容审核',
        parentId: '',
        sortNo: 0,
        status: 1,
      }),
    );
    expect(wrapper.emitted('saved')).toHaveLength(1);
    expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual([false]);
  });

  it('edits a category while retaining its legal parent', async () => {
    const wrapper = mount(SkillCategoryFormDialog, {
      props: {
        category: {
          categoryName: '平台',
          id: 2,
          levelNo: 2,
          parentId: 1,
          sortNo: 5,
          status: 1,
        },
        modelValue: true,
      },
    });
    await flushPromises();

    expect(wrapper.get('h2').text()).toBe('编辑分类');
    await wrapper.get('input').setValue('平台工具');
    await wrapper.get('.form-modal-confirm').trigger('click');
    await flushPromises();

    expect(apiMocks.updateSkillCategory).toHaveBeenCalledWith(
      expect.objectContaining({
        categoryName: '平台工具',
        id: 2,
        parentId: 1,
        sortNo: 5,
      }),
    );
    expect(apiMocks.saveSkillCategory).not.toHaveBeenCalled();
  });
});
