import React from 'react';
import ReactDOM from 'react-dom/client';

import { ILlmActionRequest, ILlmInitAction, ModalDisplayStyle } from './common/interfaces';
import { App } from './App';
import { getTargetText, isTargetCkeditor, setTargetText } from './common/textUtil';
import { getPromptStreamResponse } from './common/adminApiUtil';

// Store the React root globally to avoid remounting
let modalRoot: ReactDOM.Root | null = null;

export const initModal = (action: ILlmInitAction) => {
   // Find the modal container
   const modalContainer: Element | null = document.querySelector('[data-wpj-modal-mount]');

   if (!modalContainer) {
      console.error('Modal container with [data-wpj-modal-mount] not found.');
      return;
   }

   // Create a root if it doesn't exist
   if (!modalRoot) {
      modalRoot = ReactDOM.createRoot(modalContainer);
   }

   const dataAttr = modalContainer.getAttribute('data-wpj-modal-mount');
   const displayStyle = (dataAttr ? dataAttr : 'modal') as ModalDisplayStyle;
   // Render modal with updated data
   modalRoot.render(
      // <React.StrictMode>
      <App close={closeModal} llmAction={action} displayStyle={displayStyle} />,
      // </React.StrictMode>,
   );
};

let applyGlobalAbort: ((reason?: string) => void) | null = null;

export const applyAction = (action: ILlmInitAction, buttonId?: string) => {
   const body: ILlmActionRequest = {
      ...action,
      text: getTargetText(action.target),
   };

   const buttonEl = document.getElementById(buttonId ?? '');
   buttonEl?.classList.add('is-submitting');

   // eslint-disable-next-line @typescript-eslint/no-unused-expressions
   applyGlobalAbort && applyGlobalAbort('applyUser');
   applyGlobalAbort = null;

   let result = '';

   // throttle update interval, because ckeditor behaves weirdly when update interval is too fast
   let updateInterval: any = null;

   updateInterval =
      isTargetCkeditor(action.target) &&
      setInterval(() => {
         setTargetText(action.target, result);
      }, 700);
   const request = getPromptStreamResponse(body, (partialResponse) => {
      result = partialResponse;
      !isTargetCkeditor(action.target) && setTargetText(action.target, result);
   });
   applyGlobalAbort = request.abort;
   request.promise
      .then(() => {
         setTargetText(action.target, result);
         buttonEl?.classList.remove('is-submitting');
      })
      .catch((reason) => {
         if (reason !== 'applyUser') {
            buttonEl?.classList.remove('is-submitting');
         }
      })
      .finally(() => {
         updateInterval && clearInterval(updateInterval);
      });
};

export const cancelAction = () => {
   // eslint-disable-next-line @typescript-eslint/no-unused-expressions
   applyGlobalAbort && applyGlobalAbort();
   applyGlobalAbort = null;
};

export function closeModal() {
   if (modalRoot) {
      modalRoot.unmount();
      modalRoot = null;
      window.parent.postMessage({
         event: 'llm-modal-closed',
      });
   }
}
