import { mount, flushPromises } from '@vue/test-utils';
import { beforeEach, expect, it, vi } from 'vitest';
const mocks = vi.hoisted(() => ({ on: vi.fn(), off: vi.fn(), cancel: vi.fn(), refresh: vi.fn(), resume: vi.fn() }));
vi.mock('#/utils/jnpf', () => ({ onlineUtils: { getEmitter: () => ({ on: mocks.on, off: mocks.off }) } }));
vi.mock('../dmsReprint', () => ({
  REPRINT_LOCK_EVENT: 'lock',
  REPRINT_COMPLETED_EVENT: 'completed',
  cancelDmsReprint: mocks.cancel,
  refreshDmsReprintLock: mocks.refresh,
  resumeDmsReprint: mocks.resume,
}));
vi.mock('@jnpf/ui/modal', () => ({ BasicModal: { props: ['open'], template: '<div v-if="open"><slot/><slot name="footer"/></div>' } }));
vi.mock('ant-design-vue', () => ({
  Button: { props: ['disabled'], template: '<button :disabled="disabled"><slot/></button>' },
  Alert: { props: ['message'], template: '<div>{{message}}</div>' },
  Spin: { template: '<div><slot/></div>' },
  Descriptions: { template: '<div><slot/></div>' },
  DescriptionsItem: { template: '<div><slot/></div>' },
}));
import Modal from '../DmsReprintStatusModal.vue';
const base = { locked: true, printRecordId: 'copy', requestId: 'request', owner: true, phase: 'READY', canCancel: true, canResume: true };
async function open(status = base) {
  const wrapper = mount(Modal);
  mocks.on.mock.calls.find(([name]) => name === 'lock')![1]({ status });
  await flushPromises();
  return wrapper;
}
async function click(wrapper: ReturnType<typeof mount>, label: string) {
  await wrapper
    .findAll('button')
    .find((b) => b.text() === label)!
    .trigger('click');
  await flushPromises();
}
beforeEach(() => vi.resetAllMocks());
it('shows another owner without cancellation or resume', async () => {
  const w = await open({ ...base, owner: false, canCancel: false, canResume: false });
  expect(w.text()).toContain('原发起人');
  expect(w.text()).not.toContain('取消重打并解除锁定');
  expect(w.text()).not.toContain('继续重打');
  w.unmount();
  expect(mocks.off).toHaveBeenCalled();
});
it('unknown results only allow refreshing receipts', async () => {
  const w = await open({ ...base, phase: 'UNKNOWN', canCancel: false, canResume: false });
  expect(w.text()).toContain('不能取消或重复打印');
  expect(w.text()).not.toContain('确认取消');
  w.unmount();
});
it('requires inline confirmation and preserves lock after rejected cancellation', async () => {
  mocks.cancel.mockRejectedValue(new Error('任务已派发'));
  const w = await open();
  await click(w, '取消重打并解除锁定');
  expect(mocks.cancel).not.toHaveBeenCalled();
  await click(w, '确认取消');
  expect(w.text()).toContain('任务已派发');
  expect(mocks.refresh).not.toHaveBeenCalled();
  expect(mocks.resume).not.toHaveBeenCalled();
  w.unmount();
});
it('disables actions during cancellation and refreshes on success', async () => {
  let resolve!: () => void;
  mocks.cancel.mockReturnValue(new Promise<void>((r) => (resolve = r)));
  mocks.refresh.mockResolvedValue({ ...base, locked: false, canResume: false, canCancel: false });
  const w = await open();
  await click(w, '取消重打并解除锁定');
  await click(w, '确认取消');
  expect(w.findAll('button').every((b) => b.attributes('disabled') !== undefined)).toBe(true);
  resolve();
  await flushPromises();
  expect(w.text()).toContain('占用已解除');
  expect(mocks.resume).not.toHaveBeenCalled();
  w.unmount();
});
it('offers registration recovery for confirmed submission', async () => {
  mocks.resume.mockResolvedValue(undefined);
  const w = await open({ ...base, phase: 'REGISTRATION_PENDING', canCancel: false });
  await click(w, '补登记');
  expect(mocks.resume).toHaveBeenCalledWith('copy', 'request', undefined, undefined, undefined);
  expect(mocks.cancel).not.toHaveBeenCalled();
  w.unmount();
});

it('late completion clears only the matching displayed lock', async () => {
  const w = await open({ ...base, phase: 'UNKNOWN', canCancel: false, canResume: false });
  const complete = mocks.on.mock.calls.find(([name]) => name === 'completed')![1];
  complete({ printRecordId: 'other', requestId: 'request' });
  await flushPromises();
  expect(w.text()).toContain('不能取消或重复打印');
  complete({ printRecordId: 'copy', requestId: 'request' });
  await flushPromises();
  expect(w.text()).toContain('占用已解除');
  expect(w.text()).not.toContain('刷新状态 / 补交回执');
  expect(mocks.cancel).not.toHaveBeenCalled();
  w.unmount();
});

it('closes the status dialog before resuming and restores it on failure', async () => {
  let reject!: (error: Error) => void;
  mocks.resume.mockReturnValue(
    new Promise((_, r) => {
      reject = r;
    }),
  );
  const w = await open();
  await click(w, '继续重打');
  expect(w.findAll('button')).toHaveLength(0);
  expect(mocks.resume).toHaveBeenCalledTimes(1);
  reject(new Error('预览加载失败'));
  await flushPromises();
  expect(w.text()).toContain('预览加载失败');
  expect(w.text()).toContain('继续重打');
  w.unmount();
});
