/* @vitest-environment happy-dom */
/* eslint-disable vue/one-component-per-file */

import type { DmsFileCenterItem } from '#/api/x/dms/fileCenter';

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

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

import FileOperationLogModal from '../FileOperationLogModal.vue';

const apiMocks = vi.hoisted(() => ({ getFileOperationLogs: vi.fn() }));
const messageMocks = vi.hoisted(() => ({ error: vi.fn() }));
const modalState = vi.hoisted(() => ({ init: undefined as ((data: { item: DmsFileCenterItem }) => void) | undefined }));
const tableState = vi.hoisted(() => ({ config: undefined as any, pagination: { current: 1, pageSize: 10 } }));

vi.mock('#/api/x/dms/fileCenter', () => ({ getFileOperationLogs: apiMocks.getFileOperationLogs }));
vi.mock('@jnpf/hooks', () => ({ useMessage: () => ({ createMessage: messageMocks }) }));
vi.mock('@jnpf/utils', () => ({ formatToDateTime: (value: string) => value }));

vi.mock('@jnpf/ui/modal', async () => {
  const { defineComponent, h } = await import('vue');

  return {
    BasicModal: defineComponent({
      name: 'BasicModal',
      setup:
        (_, { slots }) =>
        () =>
          h('section', slots.default?.()),
    }),
    useModalInner: (init: (data: { item: DmsFileCenterItem }) => void) => {
      modalState.init = init;
      return [vi.fn(), {}];
    },
  };
});

vi.mock('@jnpf/ui/vxeTable', async () => {
  const { defineComponent, h } = await import('vue');

  return {
    BasicVxeTable: defineComponent({
      name: 'BasicVxeTable',
      props: {
        dataSource: { default: () => [], type: Array },
        loading: Boolean,
        pagination: { default: undefined, type: [Boolean, Object] },
      },
      emits: ['change'],
      setup(props, { emit }) {
        return () =>
          h(
            'button',
            {
              'data-current-page': (props.pagination as any)?.current,
              'data-page-size': (props.pagination as any)?.pageSize,
              'data-record-count': props.dataSource.length,
              'data-test': 'operation-log-table',
              onClick: () => {
                tableState.pagination = { current: 2, pageSize: 20 };
                emit('change', { action: 'paginate' });
              },
              type: 'button',
            },
            '操作记录',
          );
      },
    }),
    useVxeTable: (config: any) => {
      tableState.config = config;
      return [vi.fn(), { getPaginationRef: () => tableState.pagination }];
    },
  };
});

const fileItem: DmsFileCenterItem = {
  createdAt: '2026-09-01T00:00:00Z',
  documentId: 'document-1',
  fileName: '质量手册.docx',
  id: 'version-1',
  name: '质量手册.docx',
  resourceType: 'FILE_VERSION',
  versionNo: 1,
};

describe('file operation log modal', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    tableState.pagination = { current: 1, pageSize: 10 };
    apiMocks.getFileOperationLogs.mockResolvedValue({
      data: {
        currentPage: 1,
        list: [{ id: 'log-1', occurredAt: '2026-09-20T08:00:00Z', operationContent: '查看文件' }],
        pageSize: 10,
        total: 21,
      },
    });
  });

  it('uses the standard table as a controlled paginated view', async () => {
    const wrapper = mount(FileOperationLogModal, {
      global: {
        stubs: {
          'a-alert': true,
          'a-button': true,
          'a-tooltip': true,
          'jnpf-input': true,
        },
      },
    });

    modalState.init?.({ item: fileItem });
    await flushPromises();

    expect(tableState.config).toMatchObject({ rowKey: 'id', showIndexColumn: false, showTableSetting: false });
    expect(apiMocks.getFileOperationLogs).toHaveBeenLastCalledWith(fileItem.id, {
      currentPage: 1,
      keyword: undefined,
      pageSize: 10,
    });

    const table = wrapper.get('[data-test="operation-log-table"]');
    expect(table.attributes('data-record-count')).toBe('1');
    expect(table.attributes('data-current-page')).toBe('1');
    expect(table.attributes('data-page-size')).toBe('10');

    apiMocks.getFileOperationLogs.mockResolvedValueOnce({
      data: { currentPage: 2, list: [], pageSize: 20, total: 21 },
    });
    await table.trigger('click');
    await flushPromises();

    expect(apiMocks.getFileOperationLogs).toHaveBeenLastCalledWith(fileItem.id, {
      currentPage: 2,
      keyword: undefined,
      pageSize: 20,
    });

    wrapper.unmount();
  });
});
