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

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

import FormulaForm from '../FormulaForm.vue';

const apiMocks = vi.hoisted(() => ({ createFormula: vi.fn(), createFormulaDraft: vi.fn() }));
const formState = vi.hoisted(() => ({ config: undefined as any, resetFields: vi.fn(), setFieldsValue: vi.fn(), validate: vi.fn() }));
const messageState = vi.hoisted(() => ({ success: vi.fn() }));
const modalState = vi.hoisted(() => ({ closeModal: vi.fn(), init: undefined as any }));

vi.mock('#/api/x/eln/formulas', () => ({ createFormula: apiMocks.createFormula, createFormulaDraft: apiMocks.createFormulaDraft }));
vi.mock('@jnpf/hooks', () => ({ useMessage: () => ({ createMessage: messageState }) }));
vi.mock('@jnpf/ui/form', () => ({
  BasicForm: { name: 'BasicForm', template: '<div />' },
  useForm: (config: any) => {
    formState.config = config;
    return [vi.fn(), formState];
  },
}));
vi.mock('@jnpf/ui/modal', () => ({
  BasicModal: { name: 'BasicModal', props: ['minHeight', 'width'], template: '<div><slot /></div>' },
  useModalInner: (init: any) => {
    modalState.init = init;
    return [vi.fn(), { changeOkLoading: vi.fn(), closeModal: modalState.closeModal }];
  },
}));
vi.mock('../ParameterTable.vue', () => ({ default: { name: 'ParameterTable', template: '<div />' } }));

describe('eLN formula creation form', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    formState.validate.mockResolvedValue({
      beizhu: ' 初始草稿 ',
      biaodashi: 'a + b',
      gongshiMingcheng: '含量计算',
      jieguoLeixing: 'DECIMAL',
      xiuyueMoshi: 'HALF_UP',
      xiuyueXiaoshuWei: 2,
      yewuYongtu: ' 含量 ',
    });
    apiMocks.createFormula.mockResolvedValue({ data: {}, msg: '创建成功' });
    apiMocks.createFormulaDraft.mockResolvedValue({ data: { id: 'formula-1', versions: [] }, msg: 'success' });
  });

  it('does not expose a formula code input because the backend creates identity', () => {
    shallowMount(FormulaForm);
    expect(formState.config.schemas.map((item: any) => item.field)).not.toContain('gongshiBianma');
  });

  it('only collects definition metadata and parameter slots before opening the editor', () => {
    shallowMount(FormulaForm);
    expect(formState.config.schemas.map((item: any) => item.field)).toEqual(['gongshiMingcheng', 'yewuYongtu', 'beizhu']);
    expect(formState.config.schemas.find((item: any) => item.field === 'beizhu').componentProps.placeholder).toBe('请输入备注');
  });

  it('provides enough space for parameter editing', () => {
    const wrapper = shallowMount(FormulaForm);
    const modal = wrapper.findComponent({ name: 'BasicModal' });

    expect(modal.props('width')).toBe('960px');
    expect(modal.props('minHeight')).toBe(560);
  });

  it('creates a draft and emits its returned detail for the catalog to open', async () => {
    const wrapper = shallowMount(FormulaForm);
    modalState.init({});
    wrapper.findComponent({ name: 'BasicModal' }).vm.$emit('ok');
    await flushPromises();
    expect(apiMocks.createFormulaDraft).toHaveBeenCalledWith({ beizhu: '初始草稿', gongshiMingcheng: '含量计算', parameters: [], yewuYongtu: '含量' });
    expect(messageState.success).toHaveBeenCalledWith('公式创建成功');
    expect(wrapper.emitted('created')).toEqual([[{ id: 'formula-1', versions: [] }]]);
    expect(modalState.closeModal).toHaveBeenCalled();
  });
});
