import { markRaw } from 'vue';
import type { EditorConfig } from '@ckeditor/ckeditor5-core';
import type ClassicEditor from '@ckeditor/ckeditor5-build-classic';
import type { Component } from 'vue';
import FirebaseUploadAdapterPlugin from '@/utils/boardUtils/FirebaseUploadAdapter';

export interface CKEditorInstances {
  editor: typeof ClassicEditor | null;
  ckeditor: Component | null;
}

// Module-level cache
let editorInstance: typeof ClassicEditor | null = null;
let ckeditorInstance: Component | null = null;

export const loadCKEditor = async (): Promise<CKEditorInstances> => {
  // Check cache first
  if (!editorInstance || !ckeditorInstance) {
    console.log('[CKEditor Utils] Loading fresh instances...');
    try {
      // Dynamically import the modules
      const ClassicEditorModule = await import(
        '@ckeditor/ckeditor5-build-classic'
      );
      const CKEditorModule = await import('@ckeditor/ckeditor5-vue');

      // Assign the editor constructor
      if (ClassicEditorModule && ClassicEditorModule.default) {
        editorInstance = markRaw(ClassicEditorModule.default);
      } else {
        console.error(
          '[CKEditor Utils] ClassicEditorModule.default not found.'
        );
        throw new Error('ClassicEditorModule default export not found.');
      }

      // Assign the CKEditor Vue component based on named export 'Ckeditor'
      let componentDefinition: Component | null = null;
      if (CKEditorModule && CKEditorModule.Ckeditor) {
        // Check if the named export 'Ckeditor' exists
        // Assume Ckeditor export *is* the component, as the .component check caused TS errors
        componentDefinition = CKEditorModule.Ckeditor as Component;
        console.log(
          '[CKEditor Utils] Accessed component via CKEditorModule.Ckeditor (Simplified)'
        );
      } else {
        console.error(
          "[CKEditor Utils] Could not find 'Ckeditor' named export in CKEditorModule."
        );
        // Consider throwing an error if the component is essential
        throw new Error(
          "CKEditor Vue component 'Ckeditor' named export not found."
        );
      }

      // Assign the found component, wrapped in markRaw
      ckeditorInstance = componentDefinition
        ? markRaw(componentDefinition)
        : null;

      // Verify instances were assigned
      if (!editorInstance || !ckeditorInstance) {
        console.error('[CKEditor Utils] Instance assignment failed.', {
          editorInstance,
          ckeditorInstance,
        });
        throw new Error(
          'CKEditor instance assignment resulted in null values.'
        );
      }

      console.log('[CKEditor Utils] Instances loaded and cached.');
    } catch (error) {
      console.error('Error loading CKEditor modules:', error);
      // Ensure cache is cleared on error
      editorInstance = null;
      ckeditorInstance = null;
      throw error; // Re-throw error to be caught by caller
    }
  } else {
    console.log('[CKEditor Utils] Returning cached instances.');
  }

  // Final check should be redundant if error handling is correct
  if (!editorInstance || !ckeditorInstance) {
    throw new Error(
      'Attempted to return CKEditor instances but they are null.'
    );
  }

  // Return the cached or newly loaded instances
  return {
    editor: editorInstance,
    ckeditor: ckeditorInstance,
  };
};

// Editor Configuration (remains the same)
export const editorConfig: Partial<EditorConfig> = {
  extraPlugins: [FirebaseUploadAdapterPlugin],
  toolbar: {
    items: [
      'heading',
      '|',
      'bold',
      'italic',
      'link',
      '|',
      'bulletedList',
      'numberedList',
      'blockQuote',
      '|',
      'uploadImage',
      'insertTable',
      'mediaEmbed',
      '|',
      'undo',
      'redo',
    ],
  },
  language: 'ko',
  mediaEmbed: { previewsInData: true },
  image: {
    toolbar: [
      'imageTextAlternative',
      'toggleImageCaption',
      '|',
      'imageStyle:inline',
      'imageStyle:block',
      'imageStyle:side',
      '|',
      'linkImage',
    ],
  },
};

// Export the loader function as the default
export default loadCKEditor;
