/**
 * EmailWrapperView Component Tests
 *
 * Tests to cover all uncovered lines in EmailWrapperView component
 */

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import { IntlProvider } from 'react-intl';
import EmailWrapperView from '../EmailWrapperView';
import { EMAIL_CREATE_MODES, STEPS } from '../../constants';

// Mock dependencies
jest.mock('../../../../utils/common', () => ({
  hasSupportCKEditor: jest.fn(() => false),
}));

jest.mock('../../../Email', () => ({
  EmailWithoutSaga: function MockEmailWithoutSaga(props) {
    return <div data-testid="email-without-saga">Email Component</div>;
  },
}));

jest.mock('../../../../v2Components/CmsTemplatesComponent', () => {
  const React = require('react');
  return function MockCmsTemplatesComponent(props) {
    return React.createElement('div', { 'data-testid': 'cms-templates' }, 'CMS Templates');
  };
});

jest.mock('../EmailHTMLEditor', () => {
  const React = require('react');
  return React.forwardRef((props, ref) => {
    React.useImperativeHandle(ref, () => ({
      getFormDataForPreview: jest.fn(() => ({ subject: 'Test', content: '<p>Test</p>' })),
      getContentForPreview: jest.fn(() => '<p>Test</p>'),
    }));

    return (
      <div
        data-testid="email-html-editor"
        data-wait-event-context-tags={JSON.stringify(props.waitEventContextTags ?? null)}
      >
        HTML Editor
      </div>
    );
  });
});

jest.mock('../../../../v2Components/TestAndPreviewSlidebox', () => {
  const React = require('react');
  return function MockTestAndPreviewSlidebox(props) {
    return React.createElement('div', { 'data-testid': 'test-preview-slidebox' },
      React.createElement('button', { onClick: props.onClose, 'data-testid': 'close-preview' }, 'Close')
    );
  };
});

// Mock CapRadioCard to render panes with title/content
jest.mock('@capillarytech/cap-ui-library/CapRadioCard', () => {
  const React = require('react');
  return function MockCapRadioCard({ panes, selected, onChange }) {
    return (
      <div data-testid="cap-radio-card">
        {panes && panes.map((pane) => (
          <label key={pane.value || pane.key} data-testid={`radio-option-${pane.value || pane.key}`}>
            <input
              type="radio"
              value={pane.value || pane.key}
              checked={(pane.value || pane.key) === selected}
              onChange={onChange}
            />
            <span>{pane.title || pane.label}</span>
            {pane.content && <span>{pane.content}</span>}
          </label>
        ))}
      </div>
    );
  };
});

// Mock ComponentWithLabelHOC to just return the component
jest.mock('@capillarytech/cap-ui-library/assets/HOCs/ComponentWithLabelHOC', () => {
  return (Component) => Component;
});

// Mock CapUploader to render children properly
jest.mock('@capillarytech/cap-ui-library/CapUploader', () => {
  const React = require('react');
  return function MockCapUploader({ children, onChange, accept, showUploadList }) {
    return (
      <div data-testid="cap-uploader">
        {children}
      </div>
    );
  };
});

// Mock CapButton to properly handle disabled prop
jest.mock('@capillarytech/cap-ui-library/CapButton', () => {
  const React = require('react');
  return function MockCapButton({ children, disabled, ...props }) {
    return (
      <button disabled={disabled} {...props}>
        {children}
      </button>
    );
  };
});

const defaultProps = {
  isUploading: false,
  emailCreateMode: EMAIL_CREATE_MODES.HTML_EDITOR,
  step: STEPS.CREATE_TEMPLATE_CONTENT,
  isFullMode: true,
  templateName: 'Test Template',
  onTemplateNameChange: jest.fn(),
  isTemplateNameEmpty: false,
  modes: [
    { value: EMAIL_CREATE_MODES.HTML_EDITOR, title: 'HTML Editor', content: 'HTML Editor Description' },
    { value: EMAIL_CREATE_MODES.DRAG_DROP, title: 'Drag & Drop', content: 'Drag & Drop Description' },
    { value: EMAIL_CREATE_MODES.UPLOAD, title: 'Upload', content: 'Upload Description' },
  ],
  onChange: jest.fn(),
  EmailLayout: null,
  modeContent: {},
  useFileUpload: jest.fn(),
  uploadButtonLabel: 'Upload File',
  isShowEmailCreate: true,
  emailProps: {
    editor: 'HTML',
    selectedEditorMode: EMAIL_CREATE_MODES.HTML_EDITOR,
  },
  cmsTemplatesProps: {},
  metaEntities: {},
  loadingTags: false,
  injectedTags: {},
  globalActions: {},
  supportedTags: [],
  getDefaultTags: 'default',
  location: { query: {}, pathname: '/email/create' },
  currentOrgDetails: {},
  forwardedTags: {},
  selectedOfferDetails: [],
  eventContextTags: [],
  waitEventContextTags: {},
  getFormdata: jest.fn(),
  isGetFormData: false,
  getLiquidTags: jest.fn(),
  showLiquidErrorInFooter: jest.fn(),
  onValidationFail: jest.fn(),
  emailActions: {},
  Email: {},
  templateData: null,
  params: {},
  fetchingLiquidTags: false,
  createTemplateInProgress: false,
  fetchingCmsData: false,
  setIsLoadingContent: jest.fn(),
  showTestAndPreviewSlidebox: false,
  handleCloseTestAndPreview: jest.fn(),
  showTemplateName: jest.fn(),
  onHtmlEditorValidationStateChange: jest.fn(),
  moduleType: null,
};

const renderWithIntl = (props = {}) => {
  const mergedProps = { ...defaultProps, ...props };
  return render(
    <IntlProvider locale="en" messages={{}}>
      <EmailWrapperView {...mergedProps} />
    </IntlProvider>
  );
};

describe('EmailWrapperView', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('passes waitEventContextTags to EmailHTMLEditor when HTML editor is shown', () => {
    const waitMap = { b1: { eventName: 'E', blockName: 'B', tags: [] } };
    renderWithIntl({ waitEventContextTags: waitMap });
    const el = screen.getByTestId('email-html-editor');
    expect(el).toHaveAttribute('data-wait-event-context-tags', JSON.stringify(waitMap));
  });

  describe('Mode Selection UI', () => {
    it('renders mode selection when step is MODE_SELECTION', () => {
      renderWithIntl({ step: STEPS.MODE_SELECTION });
      expect(screen.getByText('HTML Editor')).toBeInTheDocument();
    });

    it('renders template name input in full mode', () => {
      renderWithIntl({
        step: STEPS.MODE_SELECTION,
        isFullMode: true,
        templateName: 'Test Template',
      });
      // Template name input should be rendered
      const inputs = screen.getAllByDisplayValue('Test Template');
      expect(inputs.length).toBeGreaterThan(0);
    });

    it('does not render template name input in library mode', () => {
      renderWithIntl({
        step: STEPS.MODE_SELECTION,
        isFullMode: false,
      });
      // Template name input should not be rendered
    });

    it('renders upload button when upload mode is selected', () => {
      renderWithIntl({
        step: STEPS.MODE_SELECTION,
        emailCreateMode: EMAIL_CREATE_MODES.UPLOAD,
      });
      expect(screen.getByText('Upload File')).toBeInTheDocument();
    });

    it('disables upload button when template name is empty in full mode', () => {
      renderWithIntl({
        step: STEPS.MODE_SELECTION,
        emailCreateMode: EMAIL_CREATE_MODES.UPLOAD,
        isFullMode: true,
        isTemplateNameEmpty: true,
      });
      // CapButton is rendered inside CapUploader, find it by text
      const uploadButton = screen.getByText('Upload File');
      expect(uploadButton).toBeDisabled();
    });

    it('shows error when template name is empty in full mode', () => {
      renderWithIntl({
        step: STEPS.MODE_SELECTION,
        emailCreateMode: EMAIL_CREATE_MODES.UPLOAD,
        isFullMode: true,
        isTemplateNameEmpty: true,
      });
      // Error message should be displayed
    });

    it('shows uploaded file name when EmailLayout exists', () => {
      const modeContent = { file: { name: 'test.html' } };
      renderWithIntl({
        step: STEPS.MODE_SELECTION,
        emailCreateMode: EMAIL_CREATE_MODES.UPLOAD,
        EmailLayout: { html: '<p>Content</p>' },
        modeContent,
      });
      expect(screen.getByText('test.html')).toBeInTheDocument();
    });

    it('handles mode change', () => {
      const onChange = jest.fn();
      renderWithIntl({
        step: STEPS.MODE_SELECTION,
        onChange,
      });
      // Mode change would be triggered by CapRadioCard
    });

    it('handles template name change', () => {
      const onTemplateNameChange = jest.fn();
      renderWithIntl({
        step: STEPS.MODE_SELECTION,
        onTemplateNameChange,
        isFullMode: true,
      });
      // Template name change would be triggered by input
    });
  });

  describe('Content Creation UI', () => {
    it('renders HTML Editor when HTML Editor mode is selected', () => {
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
      });
      expect(screen.getByTestId('email-html-editor')).toBeInTheDocument();
    });

    it('renders EmailWithoutSaga when BEE Editor mode is selected', () => {
      const { hasSupportCKEditor } = require('../../../../utils/common');
      hasSupportCKEditor.mockReturnValueOnce(true);

      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        emailProps: {
          editor: 'BEE',
          selectedEditorMode: null,
        },
      });
      expect(screen.getByTestId('email-without-saga')).toBeInTheDocument();
    });

    it('renders CMS Templates when not showing email create', () => {
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: false,
      });
      expect(screen.getByTestId('cms-templates')).toBeInTheDocument();
    });

    it('renders HTML Editor in edit mode when not explicitly BEE', () => {
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        params: { id: '123' },
        location: { query: {}, pathname: '/email/edit/123' },
      });
      expect(screen.getByTestId('email-html-editor')).toBeInTheDocument();
    });

    it('renders BEE Editor in edit mode when explicitly BEE', () => {
      const { hasSupportCKEditor } = require('../../../../utils/common');
      hasSupportCKEditor.mockReturnValueOnce(true);

      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        params: { id: '123' },
        location: { query: {}, pathname: '/email/edit/123' },
        emailProps: {
          editor: 'BEE',
          selectedEditorMode: null,
        },
      });
      expect(screen.getByTestId('email-without-saga')).toBeInTheDocument();
    });

    it('renders HTML Editor when drag drop mode is selected in create', () => {
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        emailCreateMode: EMAIL_CREATE_MODES.DRAG_DROP,
        emailProps: {
          editor: 'BEE',
          selectedEditorMode: null,
        },
      });
      // Should still render HTML Editor in new flow
    });

    it('renders HTML Editor when HTML_EDITOR mode is selected', () => {
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        emailCreateMode: EMAIL_CREATE_MODES.HTML_EDITOR,
        emailProps: {
          selectedEditorMode: EMAIL_CREATE_MODES.HTML_EDITOR,
        },
      });
      expect(screen.getByTestId('email-html-editor')).toBeInTheDocument();
    });
  });

  describe('HTML Editor Props', () => {
    it('passes correct props to HTML Editor', () => {
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        location: { query: { module: 'library' } },
        params: { id: '123' },
        templateName: 'Test Template',
        isFullMode: true,
      });
      expect(screen.getByTestId('email-html-editor')).toBeInTheDocument();
    });

    it('handles form data change callback', () => {
      const onTemplateNameChange = jest.fn();
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        onTemplateNameChange,
        templateName: 'Old Name',
      });
      // Form data change would be triggered by HTML Editor
    });
  });

  describe('Test and Preview Slidebox', () => {
    it('renders TestAndPreviewSlidebox when shown', () => {
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        showTestAndPreviewSlidebox: true,
      });
      expect(screen.getByTestId('test-preview-slidebox')).toBeInTheDocument();
    });

    it('does not render TestAndPreviewSlidebox when not shown', () => {
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        showTestAndPreviewSlidebox: false,
      });
      expect(screen.queryByTestId('test-preview-slidebox')).not.toBeInTheDocument();
    });

    it('does not render TestAndPreviewSlidebox when not HTML Editor mode', () => {
      const { hasSupportCKEditor } = require('../../../../utils/common');
      hasSupportCKEditor.mockReturnValueOnce(true);

      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        showTestAndPreviewSlidebox: true,
        emailProps: {
          editor: 'BEE',
          selectedEditorMode: null,
        },
      });
      expect(screen.queryByTestId('test-preview-slidebox')).not.toBeInTheDocument();
    });

    it('handles close test and preview', () => {
      const handleCloseTestAndPreview = jest.fn();
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        showTestAndPreviewSlidebox: true,
        handleCloseTestAndPreview,
      });
      const closeButton = screen.getByTestId('close-preview');
      fireEvent.click(closeButton);
      expect(handleCloseTestAndPreview).toHaveBeenCalled();
    });

    it('gets form data for preview from HTML Editor ref', () => {
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        showTestAndPreviewSlidebox: true,
      });
      // Form data should be retrieved from ref
      expect(screen.getByTestId('test-preview-slidebox')).toBeInTheDocument();
    });

    it('gets content for preview from HTML Editor ref', () => {
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        showTestAndPreviewSlidebox: true,
      });
      // Content should be retrieved from ref
      expect(screen.getByTestId('test-preview-slidebox')).toBeInTheDocument();
    });
  });

  describe('Loading State', () => {
    it('shows loading spinner when uploading', () => {
      renderWithIntl({
        step: STEPS.MODE_SELECTION,
        emailCreateMode: EMAIL_CREATE_MODES.UPLOAD,
        isUploading: true,
      });
      // Loading spinner should be shown
    });

    it('does not show loading spinner when not uploading', () => {
      renderWithIntl({
        step: STEPS.MODE_SELECTION,
        emailCreateMode: EMAIL_CREATE_MODES.HTML_EDITOR,
        isUploading: false,
      });
      // Loading spinner should not be shown
    });
  });

  describe('Edge Cases', () => {
    it('handles missing location params', () => {
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        location: null,
        params: null,
      });
      expect(screen.getByTestId('email-html-editor')).toBeInTheDocument();
    });

    it('handles location with query id', () => {
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        location: { query: { id: '123' }, pathname: '/email/create' },
        params: {},
      });
      expect(screen.getByTestId('email-html-editor')).toBeInTheDocument();
    });

    it('handles location with params id', () => {
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        location: { query: {}, params: { id: '123' }, pathname: '/email/create' },
        params: {},
      });
      expect(screen.getByTestId('email-html-editor')).toBeInTheDocument();
    });

    it('handles pathname with /edit/', () => {
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        location: { query: {}, pathname: '/email/edit/123' },
        params: {},
      });
      expect(screen.getByTestId('email-html-editor')).toBeInTheDocument();
    });

    it('handles empty EmailLayout gracefully', () => {
      renderWithIntl({
        step: STEPS.MODE_SELECTION,
        emailCreateMode: EMAIL_CREATE_MODES.UPLOAD,
        EmailLayout: {},
        modeContent: {},
      });
      // Should not crash
    });

    it('handles null htmlEditorRef methods gracefully', () => {
      // This would require mocking the ref to return null methods
      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        showTestAndPreviewSlidebox: true,
      });
      // Should handle gracefully if ref methods don't exist
    });
  });

  describe('Issue 1: Beefree template should open in Beefree editor in Edit mode', () => {
    beforeEach(() => {
      const { hasSupportCKEditor } = require('../../../../utils/common');
      hasSupportCKEditor.mockReturnValue(false); // New flow
    });

    it('should render Email component (not HTML editor) when editing Beefree template', () => {
      const emailPropsWithBEE = {
        ...defaultProps.emailProps,
        editor: 'BEE',
        selectedEditorMode: null,
      };

      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        emailProps: emailPropsWithBEE,
        emailCreateMode: EMAIL_CREATE_MODES.DRAG_DROP,
        params: { id: 'beefree-template-1' },
        location: { query: {}, pathname: '/email/edit/beefree-template-1' },
      });

      // Should render Email component (BEE editor), not HTML editor
      expect(screen.queryByTestId('email-html-editor')).not.toBeInTheDocument();
      // Email component would be rendered (we're using EmailWithoutSaga which doesn't have a testid)
    });

    it('should render HTML editor when editing non-Beefree template', () => {
      const emailPropsWithHTML = {
        ...defaultProps.emailProps,
        editor: 'HTML',
        selectedEditorMode: EMAIL_CREATE_MODES.HTML_EDITOR,
      };

      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        emailProps: emailPropsWithHTML,
        emailCreateMode: EMAIL_CREATE_MODES.HTML_EDITOR,
        params: { id: 'html-template-1' },
        location: { query: {}, pathname: '/email/edit/html-template-1' },
      });

      // Should render HTML editor for non-Beefree template
      expect(screen.getByTestId('email-html-editor')).toBeInTheDocument();
    });

    it('should render Email component when emailCreateMode is DRAG_DROP in create mode', () => {
      const emailPropsWithBEE = {
        ...defaultProps.emailProps,
        editor: 'BEE',
        selectedEditorMode: null,
      };

      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        emailProps: emailPropsWithBEE,
        emailCreateMode: EMAIL_CREATE_MODES.DRAG_DROP,
        params: {},
        location: { query: {}, pathname: '/email/create' },
      });

      // Should render Email component (BEE editor), not HTML editor
      expect(screen.queryByTestId('email-html-editor')).not.toBeInTheDocument();
    });
  });

  describe('Issue 2: Upload Zip should open in CKEditor when SUPPORT_CK_EDITOR is enabled', () => {
    beforeEach(() => {
      const { hasSupportCKEditor } = require('../../../../utils/common');
      hasSupportCKEditor.mockReturnValue(true); // Legacy flow
    });

    it('should render Email component (CKEditor) for UPLOAD mode in create flow', () => {
      const emailPropsForCKEditor = {
        ...defaultProps.emailProps,
        editor: undefined, // Default CKEditor
        selectedEditorMode: null,
      };

      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        emailProps: emailPropsForCKEditor,
        emailCreateMode: EMAIL_CREATE_MODES.UPLOAD,
        EmailLayout: { html: '<p>Uploaded content</p>' },
        params: {},
        location: { query: {}, pathname: '/email/create' },
      });

      // Should render Email component (CKEditor), NOT HTML editor
      expect(screen.queryByTestId('email-html-editor')).not.toBeInTheDocument();
    });

    it('should render Email component (CKEditor) for UPLOAD mode in edit flow', () => {
      const emailPropsForCKEditor = {
        ...defaultProps.emailProps,
        editor: undefined,
        selectedEditorMode: null,
      };

      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        emailProps: emailPropsForCKEditor,
        emailCreateMode: EMAIL_CREATE_MODES.UPLOAD,
        EmailLayout: { html: '<p>Edited uploaded content</p>' },
        params: { id: 'uploaded-template-1' },
        location: { query: {}, pathname: '/email/edit/uploaded-template-1' },
      });

      // Should render Email component (CKEditor), NOT HTML editor
      expect(screen.queryByTestId('email-html-editor')).not.toBeInTheDocument();
    });

    it('should NOT render HTML editor for EDITOR mode when SUPPORT_CK_EDITOR is enabled', () => {
      const emailPropsForCKEditor = {
        ...defaultProps.emailProps,
        editor: undefined,
        selectedEditorMode: null,
      };

      renderWithIntl({
        step: STEPS.CREATE_TEMPLATE_CONTENT,
        isShowEmailCreate: true,
        emailProps: emailPropsForCKEditor,
        emailCreateMode: EMAIL_CREATE_MODES.EDITOR,
        params: {},
        location: { query: {}, pathname: '/email/create' },
      });

      // Should render Email component (CKEditor), NOT HTML editor
      expect(screen.queryByTestId('email-html-editor')).not.toBeInTheDocument();
    });
  });
});
