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

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

import PageSide from './PageSide.vue';

/* eslint-disable vue/one-component-per-file -- Inline dropdown stubs keep this component test focused. */

const DropdownStub = defineComponent({
  setup(_, { slots }) {
    return () =>
      h('div', { class: 'dropdown-stub' }, [
        slots.default?.(),
        slots.dropdown?.(),
      ]);
  },
});
const DropdownMenuStub = defineComponent({
  setup(_, { slots }) {
    return () => h('div', { class: 'dropdown-menu-stub' }, slots.default?.());
  },
});
const DropdownItemStub = defineComponent({
  props: { disabled: Boolean },
  emits: ['click'],
  setup(props, { emit, slots }) {
    return () =>
      h(
        'div',
        {
          class: 'dropdown-item-stub',
          'data-disabled': String(props.disabled),
          onClick: () => {
            if (!props.disabled) emit('click');
          },
        },
        slots.default?.(),
      );
  },
});

describe('page side', () => {
  it('keeps the existing flat menu selection and footer behavior', async () => {
    const add = vi.fn();
    const wrapper = mount(PageSide, {
      props: {
        defaultSelected: '',
        footerButton: { label: '添加', onClick: add },
        labelKey: 'name',
        menus: [
          { id: '', name: '全部' },
          { id: 'docs', name: '文档' },
        ],
        valueKey: 'id',
      },
    });

    expect(wrapper.findAll('.page-side__item')).toHaveLength(2);
    expect(wrapper.findAll('.page-side__item')[0]?.classes()).toContain(
      'is-selected',
    );

    await wrapper.findAll('.page-side__item')[1]?.trigger('click');
    expect(wrapper.emitted('change')?.[0]?.[0]).toMatchObject({ id: 'docs' });

    await wrapper.get('.page-side__footer').trigger('click');
    expect(add).toHaveBeenCalledOnce();
  });

  it('renders nested menus and emits the selected child', async () => {
    const wrapper = mount(PageSide, {
      props: {
        childrenKey: 'children',
        defaultSelected: '',
        labelKey: 'name',
        menus: [
          { id: '', name: '全部' },
          {
            children: [{ id: 2, name: '平台' }],
            id: 1,
            name: '研发',
          },
        ],
        valueKey: 'id',
      },
    });
    await flushPromises();

    expect(wrapper.findAll('.el-tree-node__content')).toHaveLength(3);
    const all = wrapper
      .findAll('.el-tree-node__content')
      .find((node) => node.text().includes('全部'));
    expect(all?.element.parentElement?.classList).toContain('is-current');
    const child = wrapper
      .findAll('.el-tree-node__content')
      .find((node) => node.text().includes('平台'));
    expect(child).toBeTruthy();
    await child?.trigger('click');
    expect(wrapper.emitted('change')?.at(-1)?.[0]).toMatchObject({ id: 2 });
  });

  it('supports per-node disabled action states', async () => {
    const edit = vi.fn();
    const remove = vi.fn();
    const wrapper = mount(PageSide, {
      global: {
        stubs: {
          ElDropdown: DropdownStub,
          ElDropdownItem: DropdownItemStub,
          ElDropdownMenu: DropdownMenuStub,
        },
      },
      props: {
        controlBtns: [
          {
            disabled: () => true,
            label: '编辑',
            onClick: edit,
          },
          { label: '删除', onClick: remove },
        ],
        labelKey: 'name',
        menus: [
          { id: '', name: '全部' },
          { id: 1, name: '研发' },
        ],
        valueKey: 'id',
      },
    });

    const actions = wrapper.findAll('.dropdown-item-stub');
    expect(actions).toHaveLength(2);
    expect(actions[0]?.attributes('data-disabled')).toBe('true');
    await actions[0]?.trigger('click');
    expect(edit).not.toHaveBeenCalled();

    await actions[1]?.trigger('click');
    expect(remove).toHaveBeenCalledOnce();
  });
});
