import React from 'react';
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';
import {
  buildCrmCreateFromSourcePayload,
  resolveCrmCreateFromSourceRecordInput,
  resolveCrmCreateFromSourceSuccessTarget,
} from '../src/create-record-from-source-action';
import {
  CrmCreateRecordFromSourceModal,
  type CrmCreateRecordFromSourceAction,
  type CrmCreateRecordFromSourceApi,
} from '../src/create-record-from-source-modal';

const apiMock = {
  executeStandardAction: vi.fn<CrmCreateRecordFromSourceApi['executeStandardAction']>(),
  previewStandardAction: vi.fn<CrmCreateRecordFromSourceApi['previewStandardAction']>(),
};

const api: CrmCreateRecordFromSourceApi = {
  executeStandardAction: (...args) => apiMock.executeStandardAction(...args),
  previewStandardAction: (...args) => apiMock.previewStandardAction(...args),
};

const baseAction: CrmCreateRecordFromSourceAction = {
  label: 'Create Quote',
  endpoint: '/services/data/v63.0/actions/standard/createQuote',
  previewEndpoint: '/services/data/v63.0/actions/standard/createQuote/preview',
  config: {
    sourceRecordInput: 'opportunityId',
    successOutput: 'quoteId',
    successObject: 'Quote',
    parentPreviewObject: 'Quote',
    childPreviewObject: 'QuoteLineItem',
    submitLabel: 'Create Quote',
  },
  inputs: [
    {
      name: 'opportunityId',
      uiMode: 'hidden',
      targetObject: 'Opportunity',
      targetFieldAPIName: 'Id',
    },
  ],
  outputs: [
    {
      name: 'quoteId',
      referenceTo: 'Quote',
    },
  ],
};

const host = {
  navigateToRecord: vi.fn(),
  refreshRecord: vi.fn(),
};

describe('create record from source source helpers', () => {
  afterEach(() => {
    cleanup();
    vi.clearAllMocks();
  });

  it('builds payload and success target from app-owned action metadata', () => {
    expect(resolveCrmCreateFromSourceRecordInput(baseAction)).toBe('opportunityId');
    expect(buildCrmCreateFromSourcePayload(baseAction, {
      Id: '006OPP000000001',
      Name: 'Expansion',
    })).toEqual({
      opportunityId: '006OPP000000001',
    });
    expect(resolveCrmCreateFromSourceSuccessTarget(baseAction, {
      quoteId: '0Q0000000000001',
    })).toEqual({
      objectApiName: 'Quote',
      recordId: '0Q0000000000001',
    });
  });

  it('falls back to hidden Id input and output reference metadata', () => {
    const action: CrmCreateRecordFromSourceAction = {
      ...baseAction,
      config: {},
    };
    expect(resolveCrmCreateFromSourceRecordInput(action)).toBe('opportunityId');
    expect(resolveCrmCreateFromSourceSuccessTarget(action, {
      quoteId: '0Q0000000000001',
    })).toEqual({
      objectApiName: 'Quote',
      recordId: '0Q0000000000001',
    });
  });

  it('executes and navigates through host services without Nexus runtime imports', async () => {
    apiMock.previewStandardAction.mockResolvedValue({
      parentPreview: { object: 'Quote', fields: {} },
      childPreview: [{ object: 'QuoteLineItem', count: 2 }],
    });
    apiMock.executeStandardAction.mockResolvedValue({ quoteId: '0Q0000000000001' });

    render(
      <CrmCreateRecordFromSourceModal
        isOpen
        onClose={vi.fn()}
        action={baseAction}
        record={{ Id: '006OPP000000001', Name: 'Expansion' }}
        host={host}
        api={api}
      />,
    );

    await waitFor(() => {
      expect(screen.getByText('2 rows')).toBeInTheDocument();
    });
    fireEvent.click(screen.getByRole('button', { name: 'Create Quote' }));

    await waitFor(() => {
      expect(apiMock.executeStandardAction).toHaveBeenCalledWith(
        '/services/data/v63.0/actions/standard/createQuote',
        [{ opportunityId: '006OPP000000001' }],
      );
    });
    expect(host.refreshRecord).toHaveBeenCalledTimes(1);
    expect(host.navigateToRecord).toHaveBeenCalledWith('Quote', '0Q0000000000001');
  });
});
