/**
 * InApp HTMLEditor Integration Tests
 *
 * Tests for InApp container integration with HTMLEditor component
 */

// Mock redux-auth-wrapper to prevent location.pathname.replace errors
jest.mock('redux-auth-wrapper/history4/redirect', () => ({
  connectedRouterRedirect: jest.fn((config) => (Component) => Component),
}));

// Mock Auth for hasInAppEditorFeatureEnabled - must be before other mocks
jest.mock('@capillarytech/cap-ui-utils', () => ({
  ...jest.requireActual('@capillarytech/cap-ui-utils'),
  Auth: {
    hasFeatureAccess: jest.fn(() => false), // Return false so hasInAppEditorFeatureEnabled returns true
  },
  GA: {
    initialize: jest.fn(),
    getCallerName: jest.fn(() => 'test'),
    tracker: {
      trackException: jest.fn(),
    },
    timeTracker: {
      stopTimer: jest.fn(),
      startTimer: jest.fn(),
    },
    setCustomDimension: jest.fn(),
  },
}));

// Mock hasInAppEditorFeatureEnabled
jest.mock('../../../utils/common', () => ({
  ...jest.requireActual('../../../utils/common'),
  hasInAppEditorFeatureEnabled: jest.fn(() => true),
  hasLiquidSupportFeature: jest.fn(() => false),
}));

// Mock HTMLEditor component - must be before imports
jest.mock('../../../v2Components/HtmlEditor', () => {
  const React = require('react');

  const MockHTMLEditor = function MockHTMLEditor({
    variant,
    initialContent,
    onContentChange,
    onSave,
    'data-test': dataTest,
  }) {
    return React.createElement(
      'div',
      { 'data-testid': dataTest || 'inapp-html-editor' },
      React.createElement('div', { 'data-testid': 'html-editor-variant' }, variant),
      React.createElement(
        'div',
        { 'data-testid': 'html-editor-initial-android' },
        initialContent?.android || ''
      ),
      React.createElement(
        'div',
        { 'data-testid': 'html-editor-initial-ios' },
        initialContent?.ios || ''
      ),
      React.createElement(
        'button',
        {
          'data-testid': 'html-editor-change-button',
          onClick: () => {
            if (onContentChange) {
              onContentChange({
                android: '<p>Updated Android HTML</p>',
                ios: '<p>Updated iOS HTML</p>',
              });
            }
          },
        },
        'Simulate Content Change'
      ),
      React.createElement(
        'button',
        {
          'data-testid': 'html-editor-save-button',
          onClick: () => {
            if (onSave) {
              onSave({
                android: '<p>Saved Android HTML</p>',
                ios: '<p>Saved iOS HTML</p>',
              });
            }
          },
        },
        'Simulate Save'
      )
    );
  };
  MockHTMLEditor.displayName = 'MockHTMLEditor';
  return {
    __esModule: true,
    default: MockHTMLEditor,
  };
});

/**
 * Mock CapDeviceContent to ensure HTMLEditor renders
 */
jest.mock('../../../v2Components/CapDeviceContent', () => {
  const React = require('react');
  const HTMLEditor = require('../../../v2Components/HtmlEditor').default;

  return function MockCapDeviceContent() {
    return (
      <div data-testid="cap-device-content">
        <HTMLEditor
          variant="inapp"
          initialContent={{ android: '', ios: '' }}
          onContentChange={jest.fn()}
          onSave={jest.fn()}
          data-test="inapp-html-editor"
        />
      </div>
    );
  };
});

jest.mock('../../../v2Components/TemplatePreview', () => {
  return function MockTemplatePreview() {
    return <div data-testid="template-preview">Template Preview</div>;
  };
});

import React from 'react';
import { render, screen, fireEvent, act } from '@testing-library/react';
import '@testing-library/jest-dom';
import { IntlProvider } from 'react-intl';
import { Provider } from 'react-redux';
import { configureStore } from '@capillarytech/vulcan-react-sdk/utils';

import history from '../../../utils/history';
import { initialReducer } from '../../../initialReducer';
import { InApp } from '../index';
import { INAPP_EDITOR_TYPES } from '../../InAppWrapper/constants';

let store;

beforeAll(() => {
  store = configureStore({}, initialReducer, history);
});

const defaultProps = {
  intl: {
    formatMessage: jest.fn((msg) => msg.defaultMessage || msg.id),
  },
  actions: {
    createInAppTemplate: jest.fn(),
    editTemplate: jest.fn(),
    getTemplateDetails: jest.fn(),
    resetEditTemplate: jest.fn(),
    clearCreateResponse: jest.fn(),
  },
  globalActions: {
    fetchSchemaForEntity: jest.fn(),
    getLiquidTags: jest.fn(),
  },
  isFullMode: true,
  onCreateComplete: jest.fn(),
  params: {},
  templateData: null,
  editData: {
    templateDetails: null,
  },
  accountData: {
    selectedWeChatAccount: {
      sourceAccountIdentifier: 'test-account',
      id: 'account-123',
      name: 'Test Account',
      configs: {
        android: '1',
        ios: '1',
      },
    },
  },
  location: {
    pathname: '/inapp/create',
    query: {},
    search: '',
  },
  supportedTags: [],
  metaEntities: {
    tags: {
      standard: [],
    },
  },
  injectedTags: [],
  getFormData: jest.fn(),
  selectedOfferDetails: null,
  currentOrgDetails: {
    accessibleFeatures: [],
  },
};

const renderComponent = (props = {}) => {
  const mergedProps = { ...defaultProps, ...props };

  return render(
    <Provider store={store}>
      <IntlProvider locale="en" messages={{}}>
        <InApp {...mergedProps} />
      </IntlProvider>
    </Provider>
  );
};

describe('InApp HTMLEditor Integration', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  describe('Template Name Editing', () => {
    test('should not truncate template name when editing', async () => {
      const showTemplateNameMock = jest.fn();

      renderComponent({
        defaultData: {
          'editor-type': INAPP_EDITOR_TYPES.HTML_EDITOR,
          'template-name': 'abcd',
        },
        showTemplateName: showTemplateNameMock,
      });

      const editor = await screen.findByTestId('inapp-html-editor');
      expect(editor).toBeInTheDocument();
      expect(showTemplateNameMock).toBeDefined();
    });

    test('should preserve template name when showTemplateName callback is provided', async () => {
      const showTemplateNameMock = jest.fn();

      renderComponent({
        defaultData: {
          'editor-type': INAPP_EDITOR_TYPES.HTML_EDITOR,
          'template-name': 'test',
        },
        showTemplateName: showTemplateNameMock,
      });

      const editor = await screen.findByTestId('inapp-html-editor');
      expect(editor).toBeInTheDocument();
      expect(showTemplateNameMock).toBeDefined();
    });
  });

  describe('TAG API Calls', () => {
    test('should only make one TAG API call when HTML Editor is used', async () => {
      const fetchSchemaForEntityMock = jest.fn();

      renderComponent({
        defaultData: { 'editor-type': INAPP_EDITOR_TYPES.HTML_EDITOR },
        globalActions: {
          ...defaultProps.globalActions,
          fetchSchemaForEntity: fetchSchemaForEntityMock,
        },
      });

      await screen.findByTestId('inapp-html-editor');

      const callCount = fetchSchemaForEntityMock.mock.calls.length;
      expect(callCount).toBeLessThanOrEqual(1);
    });
  });

  describe('Content Preservation on Layout Change', () => {
    test('should preserve HTML content when layout type changes', async () => {
      const { container } = renderComponent({
        defaultData: { 'editor-type': INAPP_EDITOR_TYPES.HTML_EDITOR },
      });

      await screen.findByTestId('inapp-html-editor');

      const changeButton = screen.getByTestId('html-editor-change-button');

      act(() => {
        fireEvent.click(changeButton);
      });

      const layoutRadios = container.querySelectorAll('input[type="radio"]');

      if (layoutRadios.length > 1) {
        act(() => {
          fireEvent.change(layoutRadios[1], {
            target: { value: 'HEADER' },
          });
        });

        const editor = await screen.findByTestId('inapp-html-editor');
        expect(editor).toBeInTheDocument();
      }
    });
  });

  describe('Layout Labels', () => {
    test('should use correct layout labels in constants', () => {
      const { INAPP_LAYOUT_DETAILS, INAPP_MESSAGE_LAYOUT_TYPES } =
        require('../constants');

      expect(INAPP_MESSAGE_LAYOUT_TYPES.TOPBANNER).toBe('HEADER');
      expect(INAPP_LAYOUT_DETAILS.HEADER).toBeDefined();

      expect(INAPP_MESSAGE_LAYOUT_TYPES.BOTTOMBANNER).toBe('FOOTER');
      expect(INAPP_LAYOUT_DETAILS.FOOTER).toBeDefined();
    });
  });

  describe('Device Content Support', () => {
    test('should allow creating template with Android-only content when both devices supported', async () => {
      renderComponent({
        defaultData: { 'editor-type': INAPP_EDITOR_TYPES.HTML_EDITOR },
      });

      await screen.findByTestId('inapp-html-editor');

      const changeButton = screen.getByTestId('html-editor-change-button');

      act(() => {
        fireEvent.click(changeButton);
      });

      expect(screen.getByTestId('inapp-html-editor')).toBeInTheDocument();
    });
  });
});

