import React, { useCallback } from 'react';
import { Box, config, Header, IconButton, Modal, Overlay, OverlayBackdrop, OverlayCenter, Scroll, Text } from 'folds';
import { Icon, Icons } from '../../components/icons';
import FocusTrap from 'focus-trap-react';
import { useAtomValue } from 'jotai';
import { useAllJoinedRoomsSet, useGetRoom } from '../../hooks/useGetRoom';
import { SpaceProvider } from '../../hooks/useSpace';
import { CreateRoomForm } from './CreateRoom';
import {
  useCloseCreateRoomModal,
  useCreateRoomModalState,
} from '../../state/hooks/createRoomModal';
import { CreateRoomModalState } from '../../state/createRoomModal';
import { stopPropagation } from '../../utils/keyboard';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { StateEvent } from '../../../types/matrix/room';
import { PaarrotSubRoomsContent } from '../../hooks/useRoomSubRooms';
import { roomToParentsAtom } from '../../state/room/roomToParents';
import { isSpace } from '../../utils/room';

type CreateRoomModalProps = {
  state: CreateRoomModalState;
};
function CreateRoomModal({ state }: CreateRoomModalProps) {
  const { spaceId, parentSubRoomId } = state;
  const mx = useMatrixClient();
  const closeDialog = useCloseCreateRoomModal();
  const roomToParents = useAtomValue(roomToParentsAtom);

  const allJoinedRooms = useAllJoinedRoomsSet();
  const getRoom = useGetRoom(allJoinedRooms);
  const space = spaceId ? getRoom(spaceId) : undefined;
  const parentRoom = parentSubRoomId ? getRoom(parentSubRoomId) : undefined;

  const handleCreate = useCallback(
    async (newRoomId: string) => {
      // If creating a sub-room, add it to the parent's sub-rooms and set parent relationship
      if (parentSubRoomId && parentRoom) {
        try {
          // Extract server from parent room ID for via servers
          const serverName = parentSubRoomId.split(':')[1] || '';
          const viaServers = serverName ? [serverName] : [];

          // Set m.space.parent on the new room pointing to parent
          await mx.sendStateEvent(
            newRoomId,
            StateEvent.SpaceParent,
            {
              canonical: true,
              via: viaServers,
            },
            parentSubRoomId
          );

          // Set m.space.child on the parent room pointing to this sub-room
          await mx.sendStateEvent(
            parentSubRoomId,
            StateEvent.SpaceChild,
            { via: viaServers },
            newRoomId
          );

          // Copy parent's join_rules to the sub-room
          const parentJoinRulesEvent = parentRoom.currentState.getStateEvents(StateEvent.RoomJoinRules, '');
          if (parentJoinRulesEvent) {
            const joinRulesContent = parentJoinRulesEvent.getContent();
            await mx.sendStateEvent(
              newRoomId,
              StateEvent.RoomJoinRules,
              joinRulesContent,
              ''
            );
          }

          // Add new room to parent's sub-rooms list
          const stateEvent = parentRoom.currentState.getStateEvents(StateEvent.PaarrotSubRooms, '');
          const currentContent = stateEvent?.getContent() as PaarrotSubRoomsContent | undefined;
          const currentChildren = currentContent?.children ?? [];
          const newContent: PaarrotSubRoomsContent = {
            children: [...currentChildren, newRoomId],
          };
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          await mx.sendStateEvent(parentSubRoomId, StateEvent.PaarrotSubRooms as any, newContent, '');

          // Also add sub-room to parent's space(s) for joining/permissions
          // The UI will hide it from the top-level display and only show it nested
          const parentSpaces = roomToParents.get(parentSubRoomId);
          if (parentSpaces) {
            const spaceIds = Array.from(parentSpaces);
            await Promise.all(
              spaceIds.map(async (parentSpaceId) => {
                const parentSpaceRoom = mx.getRoom(parentSpaceId);
                // Only add to actual spaces (not other sub-room parents)
                if (parentSpaceRoom && isSpace(parentSpaceRoom)) {
                  try {
                    const spaceServerName = parentSpaceId.split(':')[1] || '';
                    const spaceViaServers = spaceServerName ? [spaceServerName] : [];
                    // Add as m.space.child to the space
                    await mx.sendStateEvent(
                      parentSpaceId,
                      // eslint-disable-next-line @typescript-eslint/no-explicit-any
                      StateEvent.SpaceChild as any,
                      { via: spaceViaServers },
                      newRoomId
                    );
                  } catch (spaceError) {
                    // eslint-disable-next-line no-console
                    console.warn(`Failed to add sub-room to space ${parentSpaceId}:`, spaceError);
                  }
                }
              })
            );
          }
        } catch (error) {
          // eslint-disable-next-line no-console
          console.error('Failed to set up sub-room relationship:', error);
        }
      }
      closeDialog();
    },
    [mx, parentSubRoomId, parentRoom, roomToParents, closeDialog]
  );

  const modalTitle = parentSubRoomId ? 'New Sub-Room' : 'New Room';

  return (
    <SpaceProvider value={space ?? null}>
      <Overlay open backdrop={<OverlayBackdrop />}>
        <OverlayCenter>
          <FocusTrap
            focusTrapOptions={{
              initialFocus: false,
              clickOutsideDeactivates: true,
              onDeactivate: closeDialog,
              escapeDeactivates: stopPropagation,
            }}
          >
            <Modal size="300" flexHeight>
              <Box direction="Column">
                <Header
                  size="500"
                  style={{
                    padding: config.space.S200,
                    paddingLeft: config.space.S400,
                  }}
                >
                  <Box grow="Yes">
                    <Text size="H4">{modalTitle}</Text>
                  </Box>
                  <Box shrink="No">
                    <IconButton size="300" radii="300" onClick={closeDialog}>
                      <Icon src={Icons.Cross} />
                    </IconButton>
                  </Box>
                </Header>
                <Scroll size="300" hideTrack>
                  <Box
                    style={{
                      padding: config.space.S400,
                      paddingRight: config.space.S200,
                    }}
                    direction="Column"
                    gap="500"
                  >
                    <CreateRoomForm space={space} onCreate={handleCreate} />
                  </Box>
                </Scroll>
              </Box>
            </Modal>
          </FocusTrap>
        </OverlayCenter>
      </Overlay>
    </SpaceProvider>
  );
}

export function CreateRoomModalRenderer() {
  const state = useCreateRoomModalState();

  if (!state) return null;
  return <CreateRoomModal state={state} />;
}
