import {
  ConfirmationOptions,
  ConfirmationResult,
  ConfirmComponentUI,
  PrimariaInteractionService,
} from "./interaction-service";
import * as React from "react";
import { useEffect, useState, useRef } from "react";
import { createRoot } from "react-dom/client";
import { ConfirmationMessage } from "./confirmation-message.tsx";
import modalStyles from './modal-styles.css?raw'; 

const defaultOptions: ConfirmationOptions = {
  title: "Confirmació",
  showConfirmButton: true,
  showCancelButton: true,
  confirmButtonText: "Acceptar",
  cancelButtonText: "Cancel·lar",
  showCloseButton: true,
  fullCustomization: false,
  closeOnOutsideClick: false,
};

export class ParimariaInteractionServiceImpl extends PrimariaInteractionService {
  confirm<TData = undefined, TResult = undefined>(
    data: TData | undefined,
    componentUI: ConfirmComponentUI<TData, TResult>,
    options?: ConfirmationOptions | undefined
  ): Promise<ConfirmationResult<TResult | undefined>> {
    const finalOptions: ConfirmationOptions = { ...defaultOptions, ...(options || {}) };
    return new Promise((resolve) => {
      const div = document.createElement("div");
      document.body.appendChild(div);
      const wrapperHeadStyles = document.createElement("style");
      wrapperHeadStyles.textContent = modalStyles;
      document.head.appendChild(wrapperHeadStyles);
      const DialogComponent = componentUI.component;
      const DialogComponentStyles = componentUI.styles;
      let componentHeadStyles;
      if(DialogComponentStyles) {
        componentHeadStyles = document.createElement("style");
        componentHeadStyles.textContent = componentUI?.styles;
        document.head.appendChild(componentHeadStyles);
      }

      const DialogWrapper = () => {
        const [result, setResult] = useState<ConfirmationResult<TResult | undefined>>();
        const [isValid, setIsValid] = useState(true);
        const dialogComponentRef = useRef(null);
        const dialogRef = useRef<HTMLDivElement>(null);
        const modalRef = useRef<HTMLDivElement>(null);

        const isWebComponent =
          typeof DialogComponent === "function" && DialogComponent.prototype instanceof HTMLElement;

        useEffect(() => {
          window.addEventListener('keydown', handleKeydown);
        }, []);

        const handleKeydown = (event: KeyboardEvent) => {
          if (event.key === 'Escape') {
            handleClose(false);
          }
        };
        const handleOutsideClick = (event: Event) => {
          if (dialogRef.current) {
            if (event.target === modalRef.current && finalOptions.closeOnOutsideClick) {
              handleClose(false);
            }
          }
        };

        useEffect(() => {
          if (isWebComponent && dialogComponentRef.current) {
            const parent = dialogComponentRef.current;

            // ⚠ Aquí creamos la instancia del Web Component manualmente
            const wcElement = new (DialogComponent as any)();

            // Asignar propiedades manualmente
            (wcElement as any).data = data;
            (wcElement as any).setResult = setResult;
            (wcElement as any).setIsValid = setIsValid;
            (wcElement as any).confirm = () => isValid && handleClose(true);
            (wcElement as any).confirmResult = (result) => isValid && handleCloseWithResult(result);
            (wcElement as any).cancel = () => handleClose(false);

            // Agregar el Web Component al DOM
            parent.appendChild(wcElement);

            return () => {
              parent.removeChild(wcElement);
            };
          }
        }, [DialogComponent, data]);

        const handleClose = (confirmed: boolean) => {
          resolvePromise(result, confirmed);
        };

        const handleCloseWithResult = (finalResult: TResult) => {
          resolvePromise(finalResult, true);
        };

        const resolvePromise = (finalResult: TResult, confirmed: boolean) => {
          setTimeout(() => {
            const confirmationResult = {
              result: confirmed ? finalResult : undefined,
              confirmed: confirmed,
            };
            resolve(confirmationResult);
            document.body.removeChild(div);
            document.head.removeChild(wrapperHeadStyles);
            if (DialogComponentStyles)
              document.head.removeChild(componentHeadStyles);
            window.removeEventListener('keydown', handleKeydown);
          }, 300);
        };

        const getConfirmButtonVariant = () => {
          if (finalOptions.state === "error") return "error";
          if (finalOptions.state === "success") return "success";
          if (finalOptions.state === "info") return "primary";
          if (finalOptions.state === "alert") return "warning";
          return "primary";
        };

        const getCancelButtonVariant = () => {
          if (finalOptions.state) return "alternative-dark";
          return "secondary";
        };

        const _renderContent = () => {
          return isWebComponent ? (
            <div ref={dialogComponentRef} />
          ) : (
            <DialogComponent
              {...{
                data,
                setResult,
                setIsValid,
                confirm: () => isValid && handleClose(true),
                confirmResult: (result: TResult) => isValid && handleCloseWithResult(result),
                cancel: () => handleClose(false),
              }}
            />
          );
        };
        return (
          <div className="modal" ref={modalRef} onClick={handleOutsideClick} >
            <div className="dialog" ref={dialogRef}>
              {!finalOptions.fullCustomization && (
                <div className="dss-dialog-header">
                  <div className="dss-dialog-header-title">{finalOptions.title}</div>
                  {finalOptions.showCloseButton && (
                    <dss-icon-button
                      class="dss-dialog-header-close" 
                      size="md" 
                      variant="neutral" 
                      icon="close" 
                      onClick={() => handleClose(false)}
                    ></dss-icon-button>
                  )}
                </div>
              )}
              <div className={`modal-content ${finalOptions.fullCustomization ? 'full-customization' : ''}`}>
                {_renderContent()}
              </div>
              {!finalOptions.fullCustomization && (
                <div
                  className="dss-modal-footer"
                  hidden={!finalOptions.showCancelButton && !finalOptions.showConfirmButton}
                >
                  {finalOptions.showCancelButton && (
                    <dss-button
                      label={finalOptions.cancelButtonText}
                      onClick={() => handleClose(false)}
                      size="md"
                      variant={getCancelButtonVariant()}
                    />
                  )}
                  {finalOptions.showConfirmButton && (
                    <dss-button
                      onClick={() => isValid && handleClose(true)}
                      label={finalOptions.confirmButtonText}
                      disabled={!isValid}
                      size="md"
                      variant={getConfirmButtonVariant()}
                    />
                  )}
                </div>
              )}
            </div>
          </div>
        );
      };


      const root = createRoot(div);
      root.render(<DialogWrapper />);
    });
  }

  confirmMessage(
    message: string,
    options?: ConfirmationOptions | undefined,
  ): Promise<ConfirmationResult> {
    return this.confirm(message, {component: ConfirmationMessage}, options);
  }

  dispose(): void {
    // Limpiar todos los modales abiertos
    const modals = document.querySelectorAll('.modal');
    for (const modal of modals) {
      modal.remove();
    }
  }
}
