import React from "react";
import { injectIntl } from 'react-intl';
import '@testing-library/jest-dom';
import { Provider } from 'react-redux';
import { configureStore }  from '@capillarytech/vulcan-react-sdk/utils';
import history from "../../../utils/history";
import { initialReducer } from "../../../initialReducer";
import {
    render,
    screen,
  } from '../../../utils/test-utils';
import SlideBoxFooter from "../SlideBoxFooter";

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

const ComponentToRender = injectIntl(SlideBoxFooter);
const renderComponent = props => {
  const store = configureStore({}, initialReducer, history);
  return render(
    <Provider store={store}>
      <ComponentToRender {...props} />
    </Provider>,
  );
};

const baseFooterProps = {
  shouldShowDoneFooter: () => true,
  shouldShowContinueFooter: () => false,
  shouldShowFooter: () => true,
  shouldShowHeader: () => true,
  shouldShowTemplateName: () => true,
  onSave: jest.fn(),
  isFullMode: true,
  messages: {},
  slidBoxContent: 'editTemplate',
  templateStep: 'modeSelection',
  isTemplateNameEmpty: false,
  isCreatingTemplate: false,
};

describe("test for empty email empty template name", () => {
    it("check the error message and disabled button", async () => {
        const { hasSupportCKEditor } = require('../../../utils/common');
        hasSupportCKEditor.mockReturnValue(true);
        const shouldShowDoneFooter = jest.fn().mockReturnValue(true);
        const shouldShowContinueFooter = jest.fn();
        const props = {
          ...baseFooterProps,
          shouldShowDoneFooter,
          shouldShowContinueFooter,
          currentChannel: "EMAIL",
          isTemplateNameEmpty: true,
          htmlEditorValidationState: {
            isContentEmpty: false,
            issueCounts: { html: 0, label: 0, liquid: 0, total: 0 },
          },
        };
        renderComponent(props);
        const errorMessage = await screen.findByText(/template name cannot be empty/i);
        expect(errorMessage).toBeInTheDocument();
        const updateBtn = screen.getByRole('button', { name: /update/i });
        expect(updateBtn).toBeDisabled();
        renderComponent({
          ...props,
          isTemplateNameEmpty: false,
          htmlEditorValidationState: {
            isContentEmpty: false,
            issueCounts: { html: 0, label: 0, liquid: 0, total: 0 },
          },
        });
        const updateBtns = screen.getAllByRole('button', { name: /update/i });
        expect(updateBtns[1]).toBeEnabled();
    });
});

describe('shouldCheckValidation (line 79)', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('disables Save when shouldCheckValidation is true and validation has errors not acknowledged (HTML Editor, EMAIL, no CK)', () => {
    const { hasSupportCKEditor } = require('../../../utils/common');
    hasSupportCKEditor.mockReturnValue(false);
    renderComponent({
      ...baseFooterProps,
      currentChannel: 'EMAIL',
      slidBoxContent: 'editTemplate',
      htmlEditorValidationState: {
        validationComplete: true,
        hasErrors: true,
        errorsAcknowledged: false,
        isContentEmpty: false,
        issueCounts: { html: 1, label: 0, liquid: 0, total: 1 },
      },
    });
    const updateBtn = screen.getByRole('button', { name: /update/i });
    expect(updateBtn).toBeDisabled();
  });

  it('enables Save when shouldCheckValidation is true and validation complete with no blocking errors', () => {
    const { hasSupportCKEditor } = require('../../../utils/common');
    hasSupportCKEditor.mockReturnValue(false);
    renderComponent({
      ...baseFooterProps,
      currentChannel: 'EMAIL',
      slidBoxContent: 'editTemplate',
      htmlEditorValidationState: {
        validationComplete: true,
        hasErrors: false,
        errorsAcknowledged: false,
        isContentEmpty: false,
        issueCounts: { html: 0, label: 0, liquid: 0, total: 0 },
      },
    });
    const updateBtn = screen.getByRole('button', { name: /update/i });
    expect(updateBtn).toBeEnabled();
  });

  it('does not disable Save based on validation when currentChannel is not EMAIL (shouldCheckValidation false)', () => {
    const { hasSupportCKEditor } = require('../../../utils/common');
    hasSupportCKEditor.mockReturnValue(false);
    renderComponent({
      ...baseFooterProps,
      currentChannel: 'SMS',
      slidBoxContent: 'editTemplate',
      htmlEditorValidationState: {
        validationComplete: true,
        hasErrors: true,
        errorsAcknowledged: false,
        isContentEmpty: false,
        issueCounts: { html: 1, label: 0, liquid: 0, total: 1 },
      },
    });
    const updateBtn = screen.getByRole('button', { name: /update/i });
    expect(updateBtn).toBeEnabled();
  });

  it('does not disable Save based on validation when htmlEditorValidationState is not provided (shouldCheckValidation false)', () => {
    const { hasSupportCKEditor } = require('../../../utils/common');
    hasSupportCKEditor.mockReturnValue(false);
    renderComponent({
      ...baseFooterProps,
      currentChannel: 'EMAIL',
      slidBoxContent: 'editTemplate',
      htmlEditorValidationState: null,
    });
    const updateBtn = screen.getByRole('button', { name: /update/i });
    expect(updateBtn).toBeEnabled();
  });

  it('does not disable Save based on validation when hasSupportCKEditor is true (shouldCheckValidation false)', () => {
    const { hasSupportCKEditor } = require('../../../utils/common');
    hasSupportCKEditor.mockReturnValue(true);
    renderComponent({
      ...baseFooterProps,
      currentChannel: 'EMAIL',
      slidBoxContent: 'editTemplate',
      htmlEditorValidationState: {
        validationComplete: true,
        hasErrors: true,
        errorsAcknowledged: false,
        isContentEmpty: false,
        issueCounts: { html: 1, label: 0, liquid: 0, total: 1 },
      },
    });
    const updateBtn = screen.getByRole('button', { name: /update/i });
    expect(updateBtn).toBeEnabled();
  });

  it('disables Save when shouldCheckValidation true and content empty in create mode', () => {
    const { hasSupportCKEditor } = require('../../../utils/common');
    hasSupportCKEditor.mockReturnValue(false);
    renderComponent({
      ...baseFooterProps,
      currentChannel: 'EMAIL',
      slidBoxContent: 'createTemplate',
      emailCreateMode: 'html_editor',
      selectedEmailCreateMode: 'html_editor',
      htmlEditorValidationState: {
        validationComplete: true,
        hasErrors: false,
        errorsAcknowledged: false,
        isContentEmpty: true,
        issueCounts: { html: 0, label: 0, liquid: 0, total: 0 },
      },
    });
    const saveBtn = screen.getByRole('button', { name: /create/i });
    expect(saveBtn).toBeDisabled();
  });

  describe('personalization tokens handling', () => {
    it('disables Save and Test & Preview when anonymous mobile push template has personalization tokens', () => {
      const { hasSupportCKEditor } = require('../../../utils/common');
      hasSupportCKEditor.mockReturnValue(false);

      renderComponent({
        ...baseFooterProps,
        currentChannel: 'MOBILE_PUSH',
        slidBoxContent: 'editTemplate',
        showTestAndPreviewButton: true,
        restrictPersonalization: true,
        isAnonymousType: true,
        templateData: {
          versions: {
            ANDROID: {
              base: {
                title: 'Hello {{name}}',
                expandibleDetails: {
                  message: 'Body',
                },
              },
            },
          },
        },
      });

      const updateBtn = screen.getByRole('button', { name: /update/i });
      expect(updateBtn).toBeDisabled();

      const previewBtn = screen.getByRole('button', { name: /preview and test/i });
      expect(previewBtn).toBeDisabled();
    });

    it('uses hasPersonalizationTokenError prop override even when templateData has no tokens', () => {
      const { hasSupportCKEditor } = require('../../../utils/common');
      hasSupportCKEditor.mockReturnValue(false);

      renderComponent({
        ...baseFooterProps,
        currentChannel: 'MOBILE_PUSH',
        slidBoxContent: 'editTemplate',
        showTestAndPreviewButton: true,
        restrictPersonalization: true,
        isAnonymousType: true,
        templateData: {}, // no personalization tokens in template data
        hasPersonalizationTokenError: true,
      });

      const updateBtn = screen.getByRole('button', { name: /update/i });
      expect(updateBtn).toBeDisabled();

      const previewBtn = screen.getByRole('button', { name: /preview and test/i });
      expect(previewBtn).toBeDisabled();
    });

    it('does not disable buttons when isAnonymousType is false even with liquid tags', () => {
      const { hasSupportCKEditor } = require('../../../utils/common');
      hasSupportCKEditor.mockReturnValue(false);

      renderComponent({
        ...baseFooterProps,
        currentChannel: 'MOBILE_PUSH',
        slidBoxContent: 'editTemplate',
        showTestAndPreviewButton: true,
        restrictPersonalization: true,
        isAnonymousType: false, // non-anonymous user
        templateData: {
          versions: {
            ANDROID: {
              base: {
                title: 'Hello {{name}}',
                expandibleDetails: {
                  message: 'Welcome',
                },
              },
            },
          },
        },
      });

      const updateBtn = screen.getByRole('button', { name: /update/i });
      expect(updateBtn).toBeEnabled();

      const previewBtn = screen.getByRole('button', { name: /preview and test/i });
      expect(previewBtn).toBeEnabled();
    });

    it('does not disable buttons when restrictPersonalization is false even for anonymous users with tokens', () => {
      const { hasSupportCKEditor } = require('../../../utils/common');
      hasSupportCKEditor.mockReturnValue(false);

      renderComponent({
        ...baseFooterProps,
        currentChannel: 'MOBILE_PUSH',
        slidBoxContent: 'editTemplate',
        showTestAndPreviewButton: true,
        restrictPersonalization: false, // personalization is allowed
        isAnonymousType: true,
        templateData: {
          versions: {
            ANDROID: {
              base: {
                title: 'Hello {{name}}',
                expandibleDetails: {
                  message: 'Welcome',
                },
              },
            },
          },
        },
      });

      const updateBtn = screen.getByRole('button', { name: /update/i });
      expect(updateBtn).toBeEnabled();
    });

    it('detects liquid tags {{ }} in Android title and disables buttons', () => {
      const { hasSupportCKEditor } = require('../../../utils/common');
      hasSupportCKEditor.mockReturnValue(false);

      renderComponent({
        ...baseFooterProps,
        currentChannel: 'MOBILE_PUSH',
        slidBoxContent: 'editTemplate',
        restrictPersonalization: true,
        isAnonymousType: true,
        templateData: {
          versions: {
            ANDROID: {
              base: {
                title: '{{dynamicTitle}}',
                expandibleDetails: {
                  message: 'Static body',
                },
              },
            },
          },
        },
      });

      const updateBtn = screen.getByRole('button', { name: /update/i });
      expect(updateBtn).toBeDisabled();
    });

    it('detects liquid tags {{ }} in iOS message body and disables buttons', () => {
      const { hasSupportCKEditor } = require('../../../utils/common');
      hasSupportCKEditor.mockReturnValue(false);

      renderComponent({
        ...baseFooterProps,
        currentChannel: 'MOBILE_PUSH',
        slidBoxContent: 'editTemplate',
        restrictPersonalization: true,
        isAnonymousType: true,
        templateData: {
          versions: {
            IOS: {
              base: {
                title: 'Static',
                expandableDetails: {
                  message: 'Message with {{variable}}',
                },
              },
            },
          },
        },
      });

      const updateBtn = screen.getByRole('button', { name: /update/i });
      expect(updateBtn).toBeDisabled();
    });

    it('detects event context tags [ ] and disables buttons', () => {
      const { hasSupportCKEditor } = require('../../../utils/common');
      hasSupportCKEditor.mockReturnValue(false);

      renderComponent({
        ...baseFooterProps,
        currentChannel: 'MOBILE_PUSH',
        slidBoxContent: 'editTemplate',
        restrictPersonalization: true,
        isAnonymousType: true,
        templateData: {
          versions: {
            ANDROID: {
              base: {
                title: 'Hello [eventContext]',
                expandibleDetails: {
                  message: 'Body',
                },
              },
            },
          },
        },
      });

      const updateBtn = screen.getByRole('button', { name: /update/i });
      expect(updateBtn).toBeDisabled();
    });

    it('allows buttons when template has no personalization tokens', () => {
      const { hasSupportCKEditor } = require('../../../utils/common');
      hasSupportCKEditor.mockReturnValue(false);

      renderComponent({
        ...baseFooterProps,
        currentChannel: 'MOBILE_PUSH',
        slidBoxContent: 'editTemplate',
        showTestAndPreviewButton: true,
        restrictPersonalization: true,
        isAnonymousType: true,
        templateData: {
          versions: {
            ANDROID: {
              base: {
                title: 'Static Title',
                expandibleDetails: {
                  message: 'Static Message Body',
                },
              },
            },
            IOS: {
              base: {
                title: 'iOS Title',
                expandibleDetails: {
                  message: 'iOS Message',
                },
              },
            },
          },
        },
      });

      const updateBtn = screen.getByRole('button', { name: /update/i });
      expect(updateBtn).toBeEnabled();

      const previewBtn = screen.getByRole('button', { name: /preview and test/i });
      expect(previewBtn).toBeEnabled();
    });

    it('handles expandableDetails spelling variant (corrected spelling)', () => {
      const { hasSupportCKEditor } = require('../../../utils/common');
      hasSupportCKEditor.mockReturnValue(false);

      renderComponent({
        ...baseFooterProps,
        currentChannel: 'MOBILE_PUSH',
        slidBoxContent: 'editTemplate',
        restrictPersonalization: true,
        isAnonymousType: true,
        templateData: {
          versions: {
            ANDROID: {
              base: {
                title: 'Static',
                expandableDetails: { // correct spelling
                  message: 'Message with {{token}}',
                },
              },
            },
          },
        },
      });

      const updateBtn = screen.getByRole('button', { name: /update/i });
      expect(updateBtn).toBeDisabled();
    });

    it('checks both Android and iOS versions for tokens', () => {
      const { hasSupportCKEditor } = require('../../../utils/common');
      hasSupportCKEditor.mockReturnValue(false);

      renderComponent({
        ...baseFooterProps,
        currentChannel: 'MOBILE_PUSH',
        slidBoxContent: 'editTemplate',
        restrictPersonalization: true,
        isAnonymousType: true,
        templateData: {
          versions: {
            ANDROID: {
              base: {
                title: 'Android Title',
                expandibleDetails: {
                  message: 'Android Message',
                },
              },
            },
            IOS: {
              base: {
                title: 'iOS [context]',
                expandibleDetails: {
                  message: 'iOS Message',
                },
              },
            },
          },
        },
      });

      const updateBtn = screen.getByRole('button', { name: /update/i });
      expect(updateBtn).toBeDisabled();
    });

    it('returns false when templateData is null', () => {
      const { hasSupportCKEditor } = require('../../../utils/common');
      hasSupportCKEditor.mockReturnValue(false);

      renderComponent({
        ...baseFooterProps,
        currentChannel: 'MOBILE_PUSH',
        slidBoxContent: 'editTemplate',
        restrictPersonalization: true,
        isAnonymousType: true,
        templateData: null,
      });

      const updateBtn = screen.getByRole('button', { name: /update/i });
      expect(updateBtn).toBeEnabled();
    });

    it('returns false when templateData is undefined', () => {
      const { hasSupportCKEditor } = require('../../../utils/common');
      hasSupportCKEditor.mockReturnValue(false);

      renderComponent({
        ...baseFooterProps,
        currentChannel: 'MOBILE_PUSH',
        slidBoxContent: 'editTemplate',
        restrictPersonalization: true,
        isAnonymousType: true,
        templateData: undefined,
      });

      const updateBtn = screen.getByRole('button', { name: /update/i });
      expect(updateBtn).toBeEnabled();
    });
  });
});

describe('SlideBoxFooter — continue and preview states', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    const { hasSupportCKEditor } = require('../../../utils/common');
    hasSupportCKEditor.mockReturnValue(false);
  });

  it('renders the Continue button when shouldShowContinueFooter returns true', () => {
    renderComponent({
      ...baseFooterProps,
      shouldShowDoneFooter: jest.fn().mockReturnValue(false),
      shouldShowContinueFooter: jest.fn().mockReturnValue(true),
      isContinueButtonDisabled: false,
      // null lets the component fall back to messages.continue (has a valid id)
      // The defaultProp {} has no id, which causes FormattedMessage to throw
      continueButtonLabel: null,
    });
    const continueBtn = screen.getByRole('button', { name: /continue/i });
    expect(continueBtn).toBeTruthy();
    expect(continueBtn).toBeEnabled();
  });

  it('disables the Continue button when isContinueButtonDisabled is true', () => {
    renderComponent({
      ...baseFooterProps,
      shouldShowDoneFooter: jest.fn().mockReturnValue(false),
      shouldShowContinueFooter: jest.fn().mockReturnValue(true),
      isContinueButtonDisabled: true,
      continueButtonLabel: null,
    });
    const continueBtn = screen.getByRole('button', { name: /continue/i });
    expect(continueBtn).toBeDisabled();
  });

  it('renders the Edit button when slidBoxContent is preview', () => {
    renderComponent({
      ...baseFooterProps,
      slidBoxContent: 'preview',
      shouldShowDoneFooter: jest.fn().mockReturnValue(false),
      shouldShowContinueFooter: jest.fn().mockReturnValue(false),
      onEditTemplate: jest.fn(),
    });
    const editBtn = screen.getByRole('button', { name: /edit/i });
    expect(editBtn).toBeTruthy();
  });

  it('calls onEditTemplate when the Edit button is clicked in preview mode', () => {
    const onEditTemplate = jest.fn();
    renderComponent({
      ...baseFooterProps,
      slidBoxContent: 'preview',
      shouldShowDoneFooter: jest.fn().mockReturnValue(false),
      shouldShowContinueFooter: jest.fn().mockReturnValue(false),
      onEditTemplate,
    });
    screen.getByRole('button', { name: /edit/i }).click();
    expect(onEditTemplate).toHaveBeenCalled();
  });
});