import React, { ReactNode } from 'react';
import { Room } from 'matrix-js-sdk';
import { Navigate, useParams } from 'react-router-dom';
import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom';
import { IsOneOnOneProvider, RoomProvider } from '../../../hooks/useRoom';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { JoinBeforeNavigate } from '../../../features/join-before-navigate';
import { isSpace } from '../../../utils/room';
import { useIsOneOnOneRoom } from '../../../hooks/useIsOneOnOneRoom';
import { Membership } from '../../../../types/matrix/room';
import { getDirectPath } from '../../pathUtils';

// Inner provider hosts the reactive 1:1 subscription. Hooks can't run inside
// the early-return path of the parent, so we split the component once `room`
// is known to exist and not be a space.
function ResolvedRoomProvider({ room, children }: { room: Room; children: ReactNode }) {
  const isOneOnOne = useIsOneOnOneRoom(room);
  return (
    <RoomProvider key={room.roomId} value={room}>
      <IsOneOnOneProvider value={isOneOnOne}>{children}</IsOneOnOneProvider>
    </RoomProvider>
  );
}

export function DirectRouteRoomProvider({ children }: { children: ReactNode }) {
  const mx = useMatrixClient();

  const { roomIdOrAlias, eventId } = useParams();
  const roomId = useSelectedRoom();
  const room = mx.getRoom(roomId);

  // Central membership guard: invite-state rooms have no useful Room view —
  // the Accept/Decline UI lives on the inline DirectInviteRow in the panel.
  // Push deep links and legacy /home/{roomId}/ shim can both deliver an
  // invite-room id here; bounce to the bare /direct/ list so the user lands
  // on the row instead of an empty stripped-state timeline.
  if (room && room.getMyMembership() === Membership.Invite) {
    return <Navigate to={getDirectPath()} replace />;
  }

  // After P3c the Direct tab is universal — any joined non-space room renders
  // here. Spaces (= future Channels) keep their own /{spaceId}/ route.
  if (!room || isSpace(room)) {
    if (!roomIdOrAlias) return <Navigate to={getDirectPath()} replace />;
    return <JoinBeforeNavigate roomIdOrAlias={roomIdOrAlias} eventId={eventId} />;
  }

  return <ResolvedRoomProvider room={room}>{children}</ResolvedRoomProvider>;
}
