import { useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { GoldenLayout } from 'golden-layout';
import { useComputedColorScheme } from '@mantine/core';

import 'golden-layout/dist/css/goldenlayout-base.css';

import glLightHref from 'golden-layout/dist/css/themes/goldenlayout-light-theme.css?url';
import glDarkHref from 'golden-layout/dist/css/themes/goldenlayout-dark-theme.css?url';

import { useGoldenLayoutStore } from '../stores/useGoldenLayoutStore';
import { Welcome } from '../components/Welcome/Welcome';
import { ColorSchemeToggle } from '../components/ColorSchemeToggle/ColorSchemeToggle';

type Mount = { id: string; el: HTMLElement; type: 'welcome' | 'toggle' };

export function GoldenLayoutManager() {
  const hostRef = useRef<HTMLDivElement | null>(null);
  const [mounts, setMounts] = useState<Mount[]>([]);
  const { layoutConfig, setLayoutConfig } = useGoldenLayoutStore();

  const computedScheme = useComputedColorScheme('light');
  const themeLinkRef = useRef<HTMLLinkElement | null>(null);
  const glRef = useRef<GoldenLayout | null>(null);

  useEffect(() => {
    if (!hostRef.current) return;
    const gl = new GoldenLayout(hostRef.current, {
      settings: { constrainDragToContainer: true },
    });
    glRef.current = gl;

    const registerPortal = (type: Mount['type']) => {
      gl.registerComponentFactoryFunction(type, (container) => {
        const el = container.element;
        const id =
          typeof crypto !== 'undefined' && 'randomUUID' in crypto
            ? (crypto as any).randomUUID()
            : Math.random().toString(36).slice(2);

        setMounts((prev) => [...prev, { id, el, type }]);

        const obs = new MutationObserver(() => {
          if (!document.body.contains(el)) {
            setMounts((prev) => prev.filter((m) => m.id !== id));
            obs.disconnect();
          }
        });
        obs.observe(document.body, { childList: true, subtree: true });
      });
    };

    registerPortal('welcome');
    registerPortal('toggle');

    if (layoutConfig) {
      gl.loadLayout(layoutConfig);
    } else {
      gl.loadLayout({
        root: {
          type: 'row',
          content: [
            { type: 'component', componentType: 'welcome', title: 'Welcome' },
            { type: 'component', componentType: 'toggle', title: 'Theme' },
          ],
        },
      });
    }

    gl.on('stateChanged', () => {
      const saved = gl.saveLayout();
      setLayoutConfig(saved);
    });

    return () => {
      setMounts([]);
      gl.destroy();
    };
  }, []);

  useEffect(() => {
    const link = document.createElement('link');
    link.rel = 'stylesheet';
    document.head.appendChild(link);
    themeLinkRef.current = link;
    return () => link.remove();
  }, []);

  useEffect(() => {
    if (themeLinkRef.current) {
      themeLinkRef.current.href =
        computedScheme === 'dark' ? glDarkHref : glLightHref;
    }
  }, [computedScheme]);

  useEffect(() => {
    if (!hostRef.current || !glRef.current) return;
    const ro = new ResizeObserver(() => {
      if (hostRef.current && glRef.current) {
        glRef.current.updateSize(hostRef.current.clientWidth, hostRef.current.clientHeight);
      }
    });
    ro.observe(hostRef.current);
    return () => ro.disconnect();
  }, []);

  // 🚀 Clip del drag proxy a los bordes
  useEffect(() => {
    const host = hostRef.current;
    if (!host) return;

    const onMouseMove = () => {
      const proxy = document.querySelector<HTMLElement>('.lm_dragProxy');
      if (!proxy) return;

      const bounds = host.getBoundingClientRect();
      const proxyBounds = proxy.getBoundingClientRect();

      let left = proxyBounds.left;
      let top = proxyBounds.top;

      if (left < bounds.left) left = bounds.left;
      if (top < bounds.top) top = bounds.top;
      if (left + proxyBounds.width > bounds.right) {
        left = bounds.right - proxyBounds.width;
      }
      if (top + proxyBounds.height > bounds.bottom) {
        top = bounds.bottom - proxyBounds.height;
      }

      proxy.style.position = 'absolute';
      proxy.style.left = `${left - bounds.left}px`;
      proxy.style.top = `${top - bounds.top}px`;
    };

    window.addEventListener('mousemove', onMouseMove);
    return () => window.removeEventListener('mousemove', onMouseMove);
  }, []);

  return (
    <>
      <div ref={hostRef} style={{ width: '100%', height: '100%' }} />
      {mounts.map((m) =>
        createPortal(
          m.type === 'welcome' ? <Welcome /> : <ColorSchemeToggle />,
          m.el
        )
      )}
    </>
  );
}
