// Desktop / tablet right-side profile pane. Renders the same
// `UserRoomProfile` content the mobile top horseshoe shows, but as a
// flex sibling next to the chat column instead of a slide-down rail.
//
// Mounted in `Room.tsx` only when the screen size is not Mobile —
// the mobile branch keeps using the top horseshoe via
// `RoomViewProfilePanel`.

import React, { useEffect, useRef, useState } from 'react';
import { useAtomValue } from 'jotai';
import { Box, Icon, IconButton, Icons, Text, config } from 'folds';
import FocusTrap from 'focus-trap-react';
import { useTranslation } from 'react-i18next';
import { userRoomProfileAtom } from '../../state/userRoomProfile';
import { useCloseUserRoomProfile } from '../../state/hooks/userRoomProfile';
import { useOpenRoomMembersSheet } from '../../state/hooks/roomMembersSheet';
import { useIsOneOnOne, useRoom } from '../../hooks/useRoom';
import { UserRoomProfile } from '../../components/user-profile/UserRoomProfile';
import { stopPropagation } from '../../utils/keyboard';
import { PageHeader } from '../../components/page';
import { ContainerColor } from '../../styles/ContainerColor.css';
import * as css from './RoomViewProfileSidePanel.css';

export function RoomViewProfileSidePanel() {
  const { t } = useTranslation();
  const profileState = useAtomValue(userRoomProfileAtom);
  const close = useCloseUserRoomProfile();
  const room = useRoom();
  const isOneOnOne = useIsOneOnOne();
  const openMembersSheet = useOpenRoomMembersSheet();

  const open = !!profileState;
  // Inline avatar-expanded mode: the hero avatar stretches to fill
  // the card width as a square, pushing the rest of the card down in
  // the scroll container. Replaces the legacy full-pane image swap
  // which hid the name / presence / info rows. Mobile keeps the
  // full-rail swap inside `RoomViewProfilePanel` — the rail there is
  // short enough that pushing content down would just create a
  // scroll well.
  const [avatarExpanded, setAvatarExpanded] = useState(false);

  // Close profile when the room changes — atom is global state and
  // would otherwise carry the previous room's userId into this room
  // where chrome would render against the wrong member / power
  // levels.
  useEffect(() => () => close(), [room.roomId, close]);

  // Reset avatar-zoom mode whenever the rendered user changes.
  useEffect(() => {
    setAvatarExpanded(false);
  }, [profileState?.userId]);

  const profileStateRef = useRef(profileState);
  profileStateRef.current = profileState;

  const renderUserId = profileState?.userId;

  if (!open || !renderUserId) return null;

  return (
    <FocusTrap
      focusTrapOptions={{
        initialFocus: false,
        // Outside clicks pass through to the chat (`allowOutsideClick`)
        // but don't close the pane — clicking around in the chat to
        // scroll, react, or compose shouldn't dismiss the profile.
        // Explicit close is via the header's `×` or `Esc` (the latter
        // still routes through focus-trap → `onDeactivate`).
        clickOutsideDeactivates: false,
        allowOutsideClick: () => true,
        escapeDeactivates: stopPropagation,
        onDeactivate: () => {
          if (profileStateRef.current) close();
        },
        checkCanFocusTrap: () => Promise.resolve(),
      }}
      active={open}
    >
      <div className={css.panel}>
        {/* Use the same `PageHeader` (folds `Header size="600"`) the
            chat header uses, so the bottom rule lines up with the
            adjacent `RoomViewHeaderDm` row to the pixel. */}
        <PageHeader className={`${ContainerColor({ variant: 'Surface' })} ${css.header}`}>
          {/* Group rooms: leading back arrow returns to the members sheet
              (the room card) the profile replaced in this pane — the open
              hook clears the profile atom, so the panes swap in place
              (redesign item 15). 1:1 has no members sheet → no arrow.
              Call rooms neither: Room.tsx mounts the members side pane only
              when `!callView`, so opening the sheet atom from inside a call
              would close the profile into nothing AND leak a stale atom
              that auto-opens the pane in the next group room. */}
          {!isOneOnOne && !room.isCallRoom() && (
            <Box shrink="No" alignItems="Center">
              <IconButton
                fill="None"
                onClick={() => openMembersSheet(room.roomId)}
                aria-label={t('User.back')}
              >
                <Icon size="400" src={Icons.ArrowLeft} />
              </IconButton>
            </Box>
          )}
          <Box grow="Yes" alignItems="Center">
            <Text size="H4" truncate>
              {t('User.profile_title')}
            </Text>
          </Box>
          <Box shrink="No" alignItems="Center">
            <IconButton fill="None" onClick={close} aria-label={t('Room.close')}>
              <Icon size="400" src={Icons.Cross} />
            </IconButton>
          </Box>
        </PageHeader>

        <div className={css.scrollWrap}>
          <div style={{ padding: config.space.S400 }}>
            <UserRoomProfile
              userId={renderUserId}
              onAvatarClick={() => setAvatarExpanded((prev) => !prev)}
              avatarExpanded={avatarExpanded}
            />
          </div>
        </div>
      </div>
    </FocusTrap>
  );
}
