// src/components/ItemPage/sections/FormSection/FormSection.test.tsx
import { act, fireEvent, render, screen } from '@testing-library/react';

import songwhipApi from '~/lib/songwhipApi/songwhipApi';
import { useAppAlert } from '~/src/components/NextApp/lib/CoreUi';
import { FormSection } from './FormSection';

jest.mock('~/src/lib/i18n', () => ({
  __esModule: true,
  useI18n: () => ({ t: (key: string) => key, td: () => undefined }),
}));

jest.mock('~/lib/songwhipApi/songwhipApi', () => ({
  __esModule: true,
  default: jest.fn(),
}));

jest.mock('~/src/components/NextApp/lib/CoreUi', () => ({
  __esModule: true,
  useAppAlert: jest.fn(),
}));

const mockTrackEvent = jest.fn();
jest.mock('~/src/lib/tracker/useTracker', () => ({
  __esModule: true,
  useTracker: () => ({ trackEvent: mockTrackEvent }),
}));

const mockSongwhipApi = songwhipApi as jest.Mock;
const mockUseAppAlert = useAppAlert as jest.Mock;
const mockAlert = jest.fn();

const baseProps = {
  sectionId: 'form-section-1',
  formId: 'form-abc',
  sectionPath: 'main.1',
  sectionIndex: 1,
  layoutData: { item: { id: 42, type: 'customPage' } },
} as any;

describe('FormSection', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    mockUseAppAlert.mockReturnValue(mockAlert);
    mockSongwhipApi.mockResolvedValue(undefined);
  });

  it('submits form data to forms/submit with the page and form identifiers', async () => {
    render(
      <FormSection
        {...baseProps}
        fields={[
          { type: 'text', name: 'favoriteColor', label: 'Favorite Color' },
        ]}
        submit={{ label: 'Send' }}
      />
    );

    fireEvent.change(screen.getByLabelText('Favorite Color'), {
      target: { value: 'Blue' },
    });

    await act(async () => {
      fireEvent.click(screen.getByRole('button', { name: 'Send' }));
    });

    expect(mockSongwhipApi).toHaveBeenCalledWith('forms/submit', {
      method: 'POST',
      body: {
        pageId: 42,
        pageType: 'customPage',
        formId: 'form-abc',
        formData: { favoriteColor: 'Blue' },
      },
    });
  });

  it('shows a success alert after a successful submission', async () => {
    render(
      <FormSection
        {...baseProps}
        fields={[
          { type: 'text', name: 'favoriteColor', label: 'Favorite Color' },
        ]}
        submit={{ label: 'Send' }}
      />
    );

    fireEvent.change(screen.getByLabelText('Favorite Color'), {
      target: { value: 'Blue' },
    });

    await act(async () => {
      fireEvent.click(screen.getByRole('button', { name: 'Send' }));
    });

    expect(mockAlert).toHaveBeenCalledWith({
      title: 'Form submitted',
      content: 'Thank you for submitting the form.',
    });
  });

  it('blocks submission when a required field is empty', async () => {
    render(
      <FormSection
        {...baseProps}
        fields={[
          { type: 'text', name: 'email', label: 'Email', required: true },
        ]}
        submit={{ label: 'Send' }}
      />
    );

    await act(async () => {
      fireEvent.click(screen.getByRole('button', { name: 'Send' }));
    });

    expect(mockSongwhipApi).not.toHaveBeenCalled();
    expect(mockAlert).not.toHaveBeenCalled();
  });

  it('fires a fan-form-submit tracking event with the formId on success', async () => {
    render(
      <FormSection
        {...baseProps}
        fields={[
          { type: 'text', name: 'favoriteColor', label: 'Favorite Color' },
        ]}
        submit={{ label: 'Send' }}
      />
    );

    fireEvent.change(screen.getByLabelText('Favorite Color'), {
      target: { value: 'Blue' },
    });

    await act(async () => {
      fireEvent.click(screen.getByRole('button', { name: 'Send' }));
    });

    expect(mockTrackEvent).toHaveBeenCalledWith({
      type: 'fan-form-submit',
      formId: 'form-abc',
    });
    // no submitted values are sent to analytics
    expect(mockTrackEvent).not.toHaveBeenCalledWith(
      expect.objectContaining({ data: expect.anything() })
    );
    // backend keys on the same id
    expect(mockSongwhipApi).toHaveBeenCalledWith('forms/submit', {
      method: 'POST',
      body: {
        pageId: 42,
        pageType: 'customPage',
        formId: 'form-abc',
        formData: { favoriteColor: 'Blue' },
      },
    });
  });

  it('does not fire tracking on validation failure', async () => {
    render(
      <FormSection
        {...baseProps}
        fields={[
          { type: 'text', name: 'email', label: 'Email', required: true },
        ]}
        submit={{ label: 'Send' }}
      />
    );

    await act(async () => {
      fireEvent.click(screen.getByRole('button', { name: 'Send' }));
    });

    expect(mockTrackEvent).not.toHaveBeenCalled();
  });
});
