import { ReactNode, useEffect, useMemo, useState } from 'react';
import { Provider as JotaiProvider } from 'jotai';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { MemoryRouter } from 'react-router-dom';
import {
  Box,
  OverlayContainerProvider,
  PopOutContainerProvider,
  TooltipContainerProvider,
  configClass,
  varsClass,
} from 'folds';
import { MatrixClientProvider } from '@cinny/app/hooks/useMatrixClient';
import { RoomProvider, IsDirectRoomProvider } from '@cinny/app/hooks/useRoom';
import { SpecVersionsProvider } from '@cinny/app/hooks/useSpecVersions';
import { DarkTheme, ThemeContextProvider } from '@cinny/app/hooks/useTheme';
import {
  PowerLevelsContextProvider,
  type IPowerLevels,
} from '@cinny/app/hooks/usePowerLevels';
import { ContainerColor } from '@cinny/app/styles/ContainerColor.css';
import type { MatrixClient, Room } from 'matrix-js-sdk';
import { MOCK_POWER_LEVELS, createMockRoom, mocks } from './matrix';

type Props = {
  children: ReactNode;
  client?: MatrixClient;
  room?: Room;
  isDirect?: boolean;
  powerLevels?: IPowerLevels;
};

const SPEC_VERSIONS = {
  versions: ['v1.11', 'v1.12'],
  unstable_features: {
    'org.matrix.msc3916.stable': true,
  },
};

/**
 * Wraps a preview in the providers Cinny UI pieces usually expect.
 * Overlay/popout/tooltip portals stay inside the stage (not the full window).
 */
export function PlaygroundProviders({
  children,
  client,
  room,
  isDirect = false,
  powerLevels = MOCK_POWER_LEVELS as IPowerLevels,
}: Props) {
  const [portal, setPortal] = useState<HTMLDivElement | null>(null);
  const queryClient = useMemo(() => new QueryClient(), []);
  const resolvedClient = client ?? mocks.client;
  // Always provide a room with `.client` set — RoomInput/useStateEvent require it.
  const resolvedRoom = useMemo(() => {
    if (room) return room;
    return createMockRoom({ client: resolvedClient });
  }, [room, resolvedClient]);

  useEffect(() => {
    document.body.classList.add(configClass, varsClass, ...DarkTheme.classNames);
  }, []);

  return (
    <div className="preview-frame">
      <ThemeContextProvider value={DarkTheme}>
        <TooltipContainerProvider value={portal ?? undefined}>
          <PopOutContainerProvider value={portal ?? undefined}>
            <OverlayContainerProvider value={portal ?? undefined}>
              <QueryClientProvider client={queryClient}>
                <JotaiProvider>
                  <MemoryRouter>
                    <SpecVersionsProvider value={SPEC_VERSIONS}>
                      <MatrixClientProvider value={resolvedClient}>
                        <RoomProvider value={resolvedRoom}>
                          <IsDirectRoomProvider value={isDirect}>
                            <PowerLevelsContextProvider value={powerLevels}>
                              <Box
                                className={ContainerColor({ variant: 'Surface' })}
                                style={{
                                  width: '100%',
                                  minHeight: '100%',
                                  height: '100%',
                                  padding: 16,
                                  borderRadius: 8,
                                }}
                              >
                                {children}
                              </Box>
                            </PowerLevelsContextProvider>
                          </IsDirectRoomProvider>
                        </RoomProvider>
                      </MatrixClientProvider>
                    </SpecVersionsProvider>
                  </MemoryRouter>
                </JotaiProvider>
              </QueryClientProvider>
            </OverlayContainerProvider>
          </PopOutContainerProvider>
        </TooltipContainerProvider>
      </ThemeContextProvider>
      {/* Host for folds Overlay/Dialog portals — contained by .preview-frame */}
      <div className="preview-portal" ref={setPortal} />
    </div>
  );
}
