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

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

import SkillCreateDialog from './SkillCreateDialog.vue';

const apiMocks = vi.hoisted(() => ({
  saveSkill: 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 () =>
          props.open
            ? 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',
                  },
                  '创建并进入详情',
                ),
              ])
            : null;
      },
    }),
  };
});

describe('skill create dialog', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    apiMocks.saveSkill.mockResolvedValue({
      data: {
        displayName: '研究助手',
        id: 101,
        publishStatus: 'DRAFT',
      },
      errorCode: 0,
    });
  });

  it('creates a valid draft from the compact business form', async () => {
    const wrapper = mount(SkillCreateDialog, {
      props: {
        canPublish: true,
        categories: [{ categoryName: '研发', id: 8, status: 1 }],
        defaultCategoryId: 8,
        modelValue: true,
      },
    });
    await flushPromises();

    expect(wrapper.get('h2').text()).toBe('新建 Skill');
    await wrapper.get('input').setValue('研究助手');
    const radioGroup = wrapper.getComponent({ name: 'ElRadioGroup' });
    radioGroup.vm.$emit('update:modelValue', 'PUBLISH');
    await wrapper.get('.form-modal-confirm').trigger('click');
    await flushPromises();

    expect(apiMocks.saveSkill).toHaveBeenCalledWith(
      expect.objectContaining({
        categoryId: 8,
        displayName: '研究助手',
        enabled: true,
        publishStatus: 'DRAFT',
        visibilityScope: 'PRIVATE',
      }),
    );
    expect(apiMocks.saveSkill.mock.calls[0]?.[0].skillContent).toContain(
      '# Instructions',
    );
    expect(wrapper.emitted('created')?.[0]?.[0]).toMatchObject({
      intent: 'PUBLISH',
      skill: { id: 101 },
    });
    expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual([false]);
  });

  it('keeps publish intent unavailable without publish permission', async () => {
    const wrapper = mount(SkillCreateDialog, {
      props: { categories: [], modelValue: true },
    });
    await flushPromises();

    const publishOption = wrapper
      .findAllComponents({ name: 'ElRadioButton' })
      .find((option) => option.text().includes('创建后发布'));
    expect(publishOption?.props('disabled')).toBe(true);
  });
});
