/**
 * EditorContext - Context provider for HTML Editor state management
 *
 * Provides centralized state management for all editor components
 * Following React Context patterns used in the project
 */

import React, { createContext, useContext, useMemo } from 'react';
import PropTypes from 'prop-types';

// Create the context
const EditorContext = createContext(null);

// Context display name for debugging
EditorContext.displayName = 'EditorContext';

/**
 * EditorProvider - Provides editor state to all child components
 */
export const EditorProvider = ({ children, value }) => {
  // Memoize context value to prevent unnecessary re-renders
  const contextValue = useMemo(() => value, [value]);

  return (
    <EditorContext.Provider value={contextValue}>
      {children}
    </EditorContext.Provider>
  );
};

EditorProvider.propTypes = {
  children: PropTypes.node.isRequired,
  value: PropTypes.shape({
    content: PropTypes.object.isRequired,
    layout: PropTypes.object.isRequired,
    validation: PropTypes.object.isRequired,
    editorRef: PropTypes.object,
    handleLabelInsert: PropTypes.func,
    handleSave: PropTypes.func,
    readOnly: PropTypes.bool,
    isFullscreenMode: PropTypes.bool
  }).isRequired
};

/**
 * useEditorContext - Hook to access editor context
 *
 * @returns {Object} Editor context value
 * @throws {Error} If used outside of EditorProvider
 */
export const useEditorContext = () => {
  const context = useContext(EditorContext);

  if (!context) {
    throw new Error('useEditorContext must be used within an EditorProvider');
  }

  return context;
};

/**
 * withEditorContext - HOC to inject editor context as props
 *
 * @param {React.Component} WrappedComponent - Component to wrap
 * @returns {React.Component} Enhanced component with context props
 */
export const withEditorContext = (WrappedComponent) => {
  const WithEditorContextComponent = (props) => {
    const editorContext = useEditorContext();

    return (
      <WrappedComponent
        {...props}
        editorContext={editorContext}
      />
    );
  };

  WithEditorContextComponent.displayName = `withEditorContext(${WrappedComponent.displayName || WrappedComponent.name})`;

  return WithEditorContextComponent;
};

export default EditorContext;
