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

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

import SkillSettingsDialog from './SkillSettingsDialog.vue';

const apiMocks = vi.hoisted(() => ({
  updateSkill: 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', [
                h('h2', props.title),
                slots.default?.(),
                h(
                  'button',
                  {
                    class: 'form-modal-confirm',
                    disabled: props.submitting,
                    onClick: () => emit('confirm'),
                    type: 'button',
                  },
                  '保存',
                ),
              ])
            : null;
      },
    }),
  };
});

describe('skill settings dialog', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    apiMocks.updateSkill.mockResolvedValue({
      data: { displayName: '更新后的 Skill', id: 101 },
      errorCode: 0,
    });
  });

  it('updates only management settings through the shared compact modal', async () => {
    const wrapper = mount(SkillSettingsDialog, {
      props: {
        categories: [{ categoryName: '研发', id: 8, status: 1 }],
        modelValue: true,
        skill: {
          categoryId: 8,
          displayName: '原 Skill',
          id: 101,
          visibilityScope: 'PRIVATE',
        },
      },
    });
    await flushPromises();

    expect(wrapper.get('h2').text()).toBe('编辑基本信息');
    await wrapper.get('input').setValue('更新后的 Skill');
    const selects = wrapper.findAllComponents({ name: 'ElSelect' });
    selects[1]?.vm.$emit('update:modelValue', 'DEPT');
    await wrapper.get('.form-modal-confirm').trigger('click');
    await flushPromises();

    expect(apiMocks.updateSkill).toHaveBeenCalledWith(
      expect.objectContaining({
        categoryId: 8,
        displayName: '更新后的 Skill',
        id: 101,
        visibilityScope: 'DEPT',
      }),
    );
    expect(wrapper.emitted('saved')?.[0]?.[0]).toMatchObject({ id: 101 });
  });

  it('keeps category loading failure visible and retryable', async () => {
    const wrapper = mount(SkillSettingsDialog, {
      props: {
        categories: [],
        categoryLoadError: '分类加载失败，请重试',
        modelValue: true,
        skill: { displayName: '原 Skill', id: 101 },
      },
    });
    await flushPromises();

    expect(wrapper.text()).toContain('重新加载');
    const retry = wrapper
      .findAll('button')
      .find((button) => button.text().trim() === '重新加载');
    await retry?.trigger('click');
    expect(wrapper.emitted('retryCategories')).toHaveLength(1);
  });
});
