import React, {
  ChangeEvent,
  ChangeEventHandler,
  FormEventHandler,
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';
import classNames from 'classnames';
import { Box, Text, IconButton, Input, Avatar, Button, Overlay, OverlayBackdrop, OverlayCenter, Modal, Dialog, Header, config, Spinner, color, toRem } from 'folds';
import { Icon, Icons } from '../../../components/icons';
import { HexColorPicker, RgbaColorPicker, RgbaColor } from 'react-colorful';
import FocusTrap from 'focus-trap-react';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { UserProfile, useUserProfile } from '../../../hooks/useUserProfile';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../../utils/matrix';
import { UserAvatar } from '../../../components/user-avatar';
import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication';
import { useAuthenticatedMediaUrl } from '../../../hooks/useAuthenticatedMediaUrl';
import { nameInitials, getContrastingTextColor, stripAlphaFromColor, getTextShadowColor } from '../../../utils/common';
import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
import { useFilePicker } from '../../../hooks/useFilePicker';
import { useObjectURL } from '../../../hooks/useObjectURL';
import { stopPropagation } from '../../../utils/keyboard';
import { ImageEditor } from '../../../components/image-editor';
import { ModalWide } from '../../../styles/Modal.css';
import { createUploadAtom, UploadSuccess } from '../../../state/upload';
import { CompactUploadCardRenderer } from '../../../components/upload-card';
import { useCapabilities } from '../../../hooks/useCapabilities';
import { HexColorPickerPopOut } from '../../../components/HexColorPickerPopOut';
import { AngleSelector } from '../../../components/AngleSelector';
import { useUserColor, useOtherUserColor } from '../../../hooks/useUserColor';
import { useUserBanner, useOtherUserBanner } from '../../../hooks/useUserBanner';
import { useUserProfileStyle } from '../../../hooks/useUserProfileStyle';
import { useUserPresence } from '../../../hooks/useUserPresence';
import { AvatarPresence, PresenceBadge } from '../../../components/presence';
import { BreakWord, LineClamp3 } from '../../../styles/Text.css';
import colorMXID, { getColorMXIDValue } from '../../../../util/colorMXID';
import {
  embedMetadataInImage,
  detectImageFormat,
  getMimeType,
  getExtension,
  ImageMetadata,
  needsPngForMetadata,
  convertImageDataToPng,
  uint8ArrayToBlob,
} from '../../../utils/imageMetadata';
import { getCurrentAccessToken } from '../../../utils/auth';

/**
 * Banner upload component for user's profile banner
 * Stored in avatar image metadata, visible to other Paarrot users
 */
function ProfileBanner({ avatarRef, nameRef }: { avatarRef: React.RefObject<HTMLDivElement>; nameRef: React.RefObject<HTMLDivElement> }) {
  const mx = useMatrixClient();
  const useAuthentication = useMediaAuthentication();
  const userId = mx.getUserId()!;
  const profile = useUserProfile(userId);
  const presence = useUserPresence(userId);
  const [userBanner, setUserBanner, loading] = useUserBanner();
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string>();
  const [hoveredArea, setHoveredArea] = useState<string | null>(null);
  const [bannerBlobUrl, setBannerBlobUrl] = useState<string>();
  const [refreshTrigger, setRefreshTrigger] = useState(0);

  // Helper to sync Matrix client's user object with server after avatar changes
  const syncUserAvatar = useCallback(async () => {
    try {
      const updatedProfile = await mx.getProfileInfo(userId);
      const user = mx.getUser(userId);
      if (user) {
        // Manually sync avatar URL to trigger UserEvent.AvatarUrl listeners
        if (updatedProfile.avatar_url !== user.avatarUrl) {
          user.setAvatarUrl(updatedProfile.avatar_url || '');
        }
        // Manually sync display name to trigger UserEvent.DisplayName listeners
        if (updatedProfile.displayname !== user.displayName) {
          user.setDisplayName(updatedProfile.displayname || '');
        }
      }
      setRefreshTrigger((prev) => prev + 1);
    } catch (err) {
      console.error('Failed to sync user profile:', err);
    }
  }, [mx, userId]);

  const avatarUrl = profile.avatarUrl
    ? mxcUrlToHttp(mx, profile.avatarUrl, useAuthentication, 96, 96, 'crop') ?? undefined
    : undefined;

  // Larger avatar URL for the blurred cover fallback
  const avatarCoverUrl = profile.avatarUrl
    ? mxcUrlToHttp(mx, profile.avatarUrl, useAuthentication) ?? undefined
    : undefined;
  const authenticatedCoverUrl = useAuthenticatedMediaUrl(avatarCoverUrl, useAuthentication);

  const [userColor, setUserColor] = useUserColor();
  const [localColor, setLocalColor] = useState(userColor ?? '#3b82f6');
  const [savingColor, setSavingColor] = useState(false);
  const [colorError, setColorError] = useState<string>();

  useEffect(() => {
    if (userColor) {
      setLocalColor(userColor);
    }
  }, [userColor]);

  const handleColorSave = async () => {
    setSavingColor(true);
    setColorError(undefined);
    try {
      await setUserColor(localColor);
      // Sync user object to propagate changes throughout app
      await syncUserAvatar();
    } catch (e) {
      setColorError('Failed to save color');
    }
    setSavingColor(false);
  };

  const handleColorRemove = async () => {
    setSavingColor(true);
    setColorError(undefined);
    try {
      await setUserColor(undefined);
    } catch (e) {
      setColorError('Failed to remove color');
    }
    setSavingColor(false);
  };

  // Profile style settings (border color and gradient)
  const [profileStyle, setProfileStyle, styleLoading] = useUserProfileStyle();
  // Initialize with transparent alpha so saved values show in preview until user edits
  const [localBorderColor, setLocalBorderColor] = useState<RgbaColor>({ r: 59, g: 130, b: 246, a: 0 });
  const [localGradientStart, setLocalGradientStart] = useState<RgbaColor>({ r: 0, g: 0, b: 0, a: 0 });
  const [localGradientStop, setLocalGradientStop] = useState<RgbaColor>({ r: 0, g: 0, b: 0, a: 0 });
  const [localGradientDirection, setLocalGradientDirection] = useState(180); // degrees (180 = top to bottom)
  const [savingStyle, setSavingStyle] = useState(false);
  const [styleError, setStyleError] = useState<string>();
  // Track if user has started editing (to show local values in preview)
  const [editingBorder, setEditingBorder] = useState(false);
  const [editingGradient, setEditingGradient] = useState(false);

  // Helper to convert RGBA to hex with alpha (#RRGGBBAA)
  const rgbaToHex = (rgba: RgbaColor): string => {
    const r = rgba.r.toString(16).padStart(2, '0');
    const g = rgba.g.toString(16).padStart(2, '0');
    const b = rgba.b.toString(16).padStart(2, '0');
    const a = Math.round(rgba.a * 255).toString(16).padStart(2, '0');
    return `#${r}${g}${b}${a}`;
  };

  // Helper to convert hex with alpha to RGBA
  const hexToRgba = (hex: string): RgbaColor => {
    const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i.exec(hex);
    if (result) {
      return {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16),
        a: result[4] ? parseInt(result[4], 16) / 255 : 1,
      };
    }
    return { r: 59, g: 130, b: 246, a: 1 };
  };

  // Helper to parse degrees from direction string (e.g., "180deg" -> 180)
  const parseDirectionDegrees = (direction: string): number => {
    const degMatch = direction.match(/^(\d+)deg$/i);
    if (degMatch) return parseInt(degMatch[1], 10);
    // Fallback for legacy "to X" format
    const keywordMap: Record<string, number> = {
      'to top': 0,
      'to top right': 45,
      'to right': 90,
      'to bottom right': 135,
      'to bottom': 180,
      'to bottom left': 225,
      'to left': 270,
      'to top left': 315,
    };
    return keywordMap[direction.toLowerCase()] ?? 180;
  };

  // Sync local style state with loaded profile style
  useEffect(() => {
    if (profileStyle.avatarBorderColor) {
      setLocalBorderColor(hexToRgba(profileStyle.avatarBorderColor));
    }
    if (profileStyle.gradient) {
      setLocalGradientStart(hexToRgba(profileStyle.gradient.startColor));
      setLocalGradientStop(hexToRgba(profileStyle.gradient.stopColor));
      setLocalGradientDirection(parseDirectionDegrees(profileStyle.gradient.direction));
    }
  }, [profileStyle]);

  const handleBorderColorSave = async () => {
    setSavingStyle(true);
    setStyleError(undefined);
    try {
      await setProfileStyle({ avatarBorderColor: rgbaToHex(localBorderColor) });
      await syncUserAvatar();
      setEditingBorder(false);
    } catch (e) {
      setStyleError('Failed to save border color');
    }
    setSavingStyle(false);
  };

  const handleBorderColorRemove = async () => {
    setSavingStyle(true);
    setStyleError(undefined);
    try {
      await setProfileStyle({ avatarBorderColor: undefined });
      await syncUserAvatar();
      setEditingBorder(false);
      setLocalBorderColor({ r: 59, g: 130, b: 246, a: 0 });
    } catch (e) {
      setStyleError('Failed to remove border color');
    }
    setSavingStyle(false);
  };

  const handleGradientSave = async () => {
    setSavingStyle(true);
    setStyleError(undefined);
    try {
      await setProfileStyle({
        gradient: {
          direction: `${localGradientDirection}deg`,
          startColor: rgbaToHex(localGradientStart),
          stopColor: rgbaToHex(localGradientStop),
        },
      });
      await syncUserAvatar();
      setEditingGradient(false);
    } catch (e) {
      setStyleError('Failed to save gradient');
    }
    setSavingStyle(false);
  };

  const handleGradientRemove = async () => {
    setSavingStyle(true);
    setStyleError(undefined);
    try {
      await setProfileStyle({ gradient: undefined });
      await syncUserAvatar();
      setEditingGradient(false);
      setLocalGradientStart({ r: 0, g: 0, b: 0, a: 0 });
      setLocalGradientStop({ r: 0, g: 0, b: 0, a: 0 });
      setLocalGradientDirection(180);
    } catch (e) {
      setStyleError('Failed to remove gradient');
    }
    setSavingStyle(false);
  };

  const [isEditingName, setIsEditingName] = useState(false);
  const [editedName, setEditedName] = useState(profile.displayName || '');
  const [savingName, setSavingName] = useState(false);

  const [isEditingStatus, setIsEditingStatus] = useState(false);
  const [editedStatus, setEditedStatus] = useState(presence?.status || '');
  const [savingStatus, setSavingStatus] = useState(false);

  // Update edited name when profile changes
  useEffect(() => {
    if (!isEditingName) {
      setEditedName(profile.displayName || '');
    }
  }, [profile.displayName, isEditingName]);

  // Update edited status when presence changes
  useEffect(() => {
    if (!isEditingStatus) {
      setEditedStatus(presence?.status || '');
    }
  }, [presence?.status, isEditingStatus]);

  const handleAvatarClick = () => {
    pickAvatarFile('image/*');
  };

  const handleNameSave = async () => {
    if (!editedName.trim() || savingName) return;
    setSavingName(true);
    try {
      await mx.setDisplayName(editedName);
      setIsEditingName(false);
      // Force refresh to update name display
      setTimeout(() => syncUserAvatar(), 100);
    } catch (err) {
      console.error('Failed to update name:', err);
    }
    setSavingName(false);
  };

  const handleNameKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter') {
      e.preventDefault();
      handleNameSave();
    } else if (e.key === 'Escape') {
      setEditedName(profile.displayName || '');
      setIsEditingName(false);
    }
  };

  const handleStatusSave = async () => {
    if (savingStatus) return;
    setSavingStatus(true);
    try {
      await mx.setPresence({
        presence: presence?.presence || 'online',
        status_msg: editedStatus || undefined,
      });
      setIsEditingStatus(false);
      // Force refresh to update status display
      setTimeout(() => setRefreshTrigger((prev) => prev + 1), 100);
    } catch (err) {
      console.error('Failed to update status:', err);
    }
    setSavingStatus(false);
  };

  const handleStatusKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter') {
      e.preventDefault();
      handleStatusSave();
    } else if (e.key === 'Escape') {
      setEditedStatus(presence?.status || '');
      setIsEditingStatus(false);
    }
  };

  const handleRemoveStatus = async () => {
    if (savingStatus) return;
    setSavingStatus(true);
    try {
      await mx.setPresence({
        presence: presence?.presence || 'online',
        status_msg: undefined,
      });
      setEditedStatus('');
      setIsEditingStatus(false);
      // Force refresh to update UI
      setTimeout(() => setRefreshTrigger((prev) => prev + 1), 100);
    } catch (err) {
      console.error('Failed to remove status:', err);
    }
    setSavingStatus(false);
  };

  const handleRemoveAvatar = async () => {
    try {
      await mx.setAvatarUrl('');
      // Sync user object to propagate changes throughout app
      await syncUserAvatar();
    } catch (err) {
      console.error('Failed to remove avatar:', err);
    }
  };

  // Load banner as blob URL
  useEffect(() => {
    let blobUrl: string | undefined;

    const loadBanner = async () => {
      if (!userBanner) {
        setBannerBlobUrl(undefined);
        return;
      }

      const bannerHttpUrl = mxcUrlToHttp(mx, userBanner, useAuthentication);
      if (!bannerHttpUrl) {
        setBannerBlobUrl(undefined);
        return;
      }

      // Always use current session's token to avoid stale tokens during account switches
      const accessToken = getCurrentAccessToken();
      const headers: HeadersInit = {};
      if (useAuthentication && accessToken) {
        headers.Authorization = `Bearer ${accessToken}`;
      }

      try {
        const response = await fetch(bannerHttpUrl, { headers });
        if (!response.ok) {
          console.warn('Failed to fetch banner preview:', response.status);
          setBannerBlobUrl(undefined);
          return;
        }

        const blob = await response.blob();
        blobUrl = URL.createObjectURL(blob);
        setBannerBlobUrl(blobUrl);
      } catch (err) {
        console.error('Error loading banner preview:', err);
        setBannerBlobUrl(undefined);
      }
    };

    loadBanner();

    return () => {
      if (blobUrl) {
        URL.revokeObjectURL(blobUrl);
      }
    };
  }, [mx, useAuthentication, userBanner, refreshTrigger]);

  const [imageFile, setImageFile] = useState<File>();
  const imageFileURL = useObjectURL(imageFile);
  const uploadAtom = useMemo(() => {
    if (imageFile) return createUploadAtom(imageFile);
    return undefined;
  }, [imageFile]);

  const pickFile = useFilePicker(setImageFile, false);

  // Avatar-specific upload
  const [avatarFile, setAvatarFile] = useState<File>();
  const avatarUploadAtom = useMemo(() => {
    if (avatarFile) return createUploadAtom(avatarFile);
    return undefined;
  }, [avatarFile]);
  const pickAvatarFile = useFilePicker(setAvatarFile, false);

  // Warn before leaving when an upload or save is in progress
  useEffect(() => {
    if (!imageFile && !avatarFile && !saving) return undefined;
    const handleBeforeUnload = (e: BeforeUnloadEvent) => {
      e.preventDefault();
      e.returnValue = '';
    };
    window.addEventListener('beforeunload', handleBeforeUnload);
    return () => window.removeEventListener('beforeunload', handleBeforeUnload);
  }, [imageFile, avatarFile, saving]);

  const handleRemoveUpload = useCallback(() => {
    setImageFile(undefined);
  }, []);

  const handleUploaded = useCallback(
    async (upload: UploadSuccess) => {
      const { mxc } = upload;
      console.log('[ProfileBanner] Banner image uploaded, MXC:', mxc);
      setSaving(true);
      setError(undefined);
      try {
        console.log('[ProfileBanner] Calling setUserBanner...');
        await setUserBanner(mxc);
        console.log('[ProfileBanner] setUserBanner completed successfully');
        handleRemoveUpload();
        // Sync user object to propagate changes throughout app
        await syncUserAvatar();
      } catch (e: any) {
        const errorMsg = e?.message || 'Unknown error';
        console.error('[ProfileBanner] setUserBanner failed:', e);
        setError(`Failed to save banner: ${errorMsg}`);
      }
      setSaving(false);
    },
    [setUserBanner, handleRemoveUpload, syncUserAvatar]
  );

  const handleAvatarUploaded = useCallback(
    async (upload: UploadSuccess) => {
      setSaving(true);
      setError(undefined);
      try {
        // Re-embed existing banner/color/style into the new avatar when present
        const metadata: ImageMetadata = {
          banner: userBanner,
          color: userColor,
          avatarBorderColor: profileStyle.avatarBorderColor,
          gradient: profileStyle.gradient,
        };
        const hasMetadata = Boolean(
          metadata.color ||
            metadata.banner ||
            metadata.avatarBorderColor ||
            metadata.gradient
        );

        // Nothing to re-embed — use the already-uploaded MXC directly
        if (!hasMetadata) {
          await mx.setAvatarUrl(upload.mxc);
          const userId = mx.getUserId();
          if (userId) {
            const user = mx.getUser(userId);
            if (user && user.avatarUrl !== upload.mxc) {
              user.setAvatarUrl(upload.mxc);
            }
          }
          setAvatarFile(undefined);
          await syncUserAvatar();
          return;
        }

        const httpUrl = mxcUrlToHttp(mx, upload.mxc, useAuthentication);
        if (!httpUrl) throw new Error('Could not resolve uploaded avatar URL');

        // Always use current session's token to avoid stale tokens during account switches
        const accessToken = getCurrentAccessToken();
        let response = await fetch(httpUrl, {
          headers: accessToken && useAuthentication ? { Authorization: `Bearer ${accessToken}` } : undefined,
        });

        // If we got a 401 and we tried with auth, fallback to unauthenticated request
        if (!response.ok && response.status === 401 && accessToken && useAuthentication) {
          console.warn('[Profile] Auth failed (401), attempting unauthenticated fallback for avatar fetch');
          response = await fetch(httpUrl);
        }

        if (!response.ok) throw new Error('Failed to fetch uploaded avatar');
        let avatarData: ArrayBuffer | Uint8Array = await response.arrayBuffer();

        let format = detectImageFormat(avatarData);
        if (format === 'unknown') throw new Error('Unsupported avatar image format');

        // Banner / border / gradient only live in PNG tEXt — convert JPEG/WebP/GIF first
        if (format !== 'png' && needsPngForMetadata(metadata)) {
          const pngData = await convertImageDataToPng(avatarData);
          if (!pngData) throw new Error('Failed to convert avatar to PNG for metadata');
          avatarData = pngData;
          format = 'png';
        }

        const modifiedData = embedMetadataInImage(avatarData, metadata);
        if (!modifiedData) throw new Error('Failed to embed metadata in avatar');

        const mimeType = getMimeType(format);
        const extension = getExtension(format);
        const blob = uint8ArrayToBlob(modifiedData, mimeType);
        const uploadResponse = await mx.uploadContent(blob, { name: `avatar.${extension}`, type: mimeType });

        await mx.setAvatarUrl(uploadResponse.content_uri);

        const userId = mx.getUserId();
        if (userId) {
          const user = mx.getUser(userId);
          if (user && user.avatarUrl !== uploadResponse.content_uri) {
            user.setAvatarUrl(uploadResponse.content_uri);
          }
        }

        setAvatarFile(undefined);
        await syncUserAvatar();
      } catch (e: any) {
        setError(`Failed to save avatar: ${e?.message || 'Unknown error'}`);
      }
      setSaving(false);
    },
    [mx, useAuthentication, userBanner, userColor, profileStyle, syncUserAvatar]
  );

  const handleRemoveBanner = async () => {
    setSaving(true);
    setError(undefined);
    try {
      await setUserBanner(undefined);
      // Sync user object to propagate changes throughout app
      await syncUserAvatar();
    } catch (e) {
      setError('Failed to remove banner.');
    }
    setSaving(false);
  };

  // Build gradient CSS for preview (shows local editing values when user is editing,
  // otherwise falls back to saved profile style)
  const previewGradient = editingGradient
    ? `linear-gradient(${localGradientDirection}deg, ${rgbaToHex(localGradientStart)}, ${rgbaToHex(localGradientStop)})`
    : profileStyle.gradient
      ? `linear-gradient(${profileStyle.gradient.direction}, ${profileStyle.gradient.startColor}, ${profileStyle.gradient.stopColor})`
      : undefined;

  // Build border color for preview (shows local editing value when user is editing,
  // otherwise falls back to saved profile style)
  const previewBorderColor = editingBorder
    ? rgbaToHex(localBorderColor)
    : profileStyle.avatarBorderColor;

  const previewPillBgColor = previewBorderColor ? stripAlphaFromColor(previewBorderColor) : undefined;
  const previewProfileColor = userColor || getColorMXIDValue(userId);

  const previewTextShadow = `0 1px 4px ${getTextShadowColor(previewProfileColor)}`;

  return (
    <Box direction="Column" gap="300">
      <Box
        direction="Column"
        style={{
          border: `${toRem(1)} solid ${color.Surface.ContainerLine}`,
          borderRadius: toRem(8),
          width: toRem(340),
          overflow: 'hidden',
          position: 'relative',
        }}
      >
          {/* Banner/Cover wrapper - provides positioning context so status bubble is not inside the button */}
          <Box
            style={{
              position: 'relative',
              height: toRem(140),
              width: '100%',
            }}
          >
            <Box
              as="button"
              onClick={() => pickFile('image/*')}
              onMouseEnter={() => setHoveredArea('banner')}
              onMouseLeave={() => setHoveredArea(null)}
              style={{
                position: 'absolute',
                inset: 0,
                width: '100%',
                height: '100%',
                overflow: 'hidden',
                cursor: 'pointer',
                border: 'none',
                padding: 0,
                backgroundColor: bannerBlobUrl ? 'transparent' : (userColor || colorMXID(userId)),
                filter: bannerBlobUrl || authenticatedCoverUrl ? 'none' : 'brightness(50%)',
                display: 'flex',
                alignItems: 'center',
              }}
            >
              {bannerBlobUrl ? (
                <img
                  src={bannerBlobUrl}
                  alt="Banner"
                  draggable="false"
                  style={{
                    height: '100%',
                    width: '100%',
                    objectFit: 'cover',
                  }}
                />
              ) : (
                authenticatedCoverUrl && (
                  <img
                    src={authenticatedCoverUrl}
                    alt="Cover"
                    draggable="false"
                    style={{
                      height: '100%',
                      width: '100%',
                      objectFit: 'cover',
                      filter: 'blur(16px)',
                      transform: 'scale(2)',
                    }}
                  />
                )
              )}
              {/* Banner hover overlay - right side action bar */}
              {hoveredArea === 'banner' && (
                <Box
                  style={{
                    position: 'absolute',
                    right: 0,
                    top: 0,
                    bottom: 0,
                    display: 'flex',
                    alignItems: 'center',
                    padding: `0 ${toRem(12)}`,
                    background: 'linear-gradient(to left, rgba(0,0,0,0.6), transparent)',
                    gap: toRem(8),
                  }}
                >
                  <Box
                    style={{
                      backgroundColor: color.Surface.Container,
                      borderRadius: toRem(16),
                      padding: toRem(8),
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                    }}
                  >
                    <Icon size="100" src={Icons.Pencil} />
                  </Box>
                  {userBanner && (
                    <Box
                      as="button"
                      onClick={(e) => {
                        e.preventDefault();
                        e.stopPropagation();
                        handleRemoveBanner();
                      }}
                      style={{
                        backgroundColor: color.Critical.Main,
                        borderRadius: toRem(16),
                        padding: toRem(8),
                        display: 'flex',
                        alignItems: 'center',
                        justifyContent: 'center',
                        cursor: 'pointer',
                        border: 'none',
                      }}
                    >
                      <Icon size="100" src={Icons.Cross} fill="white" />
                    </Box>
                  )}
                </Box>
              )}
            </Box>
          </Box>

          {/* Avatar Container - matches UserHeroAvatarContainer height */}
          <Box
            style={{
              position: 'relative',
              height: toRem(29),
            }}
          >
            {/* Avatar - centered */}
            <Box
              style={{
                position: 'absolute',
                left: '50%',
                top: 0,
                transform: 'translate(-50%, -50%)',
                display: 'flex',
                flexDirection: 'column',
                alignItems: 'center',
                gap: toRem(8),
              }}
              onMouseEnter={() => setHoveredArea('avatar')}
              onMouseLeave={() => setHoveredArea(null)}
            >
              <Box
                as="button"
                onClick={handleAvatarClick}
                style={{
                  backgroundColor: previewBorderColor || color.Surface.Container,
                  border: 'none',
                  padding: 0,
                  cursor: 'pointer',
                  borderRadius: '50%',
                }}
              >
                <AvatarPresence
                  badgeBackgroundColor={previewBorderColor}
                  badge={
                    presence && (
                      <PresenceBadge presence={presence.presence} status={presence.status} />
                    )
                  }
                >
                  <Avatar
                    size="500"
                    style={{
                      width: toRem(72),
                      height: toRem(72),
                      outline: previewBorderColor
                        ? `${toRem(4)} solid ${previewBorderColor}`
                        : `${config.borderWidth.B600} solid ${color.Surface.Container}`,
                    }}
                  >
                    <UserAvatar
                      userId={userId}
                      src={avatarUrl}
                      alt={userId}
                      renderFallback={() => <Icon size="500" src={Icons.User} filled />}
                    />
                  </Avatar>
                </AvatarPresence>
              </Box>
              {/* Avatar action icons - shown on hover */}
              {hoveredArea === 'avatar' && (
                <Box
                  style={{
                    display: 'flex',
                    alignItems: 'center',
                    gap: toRem(4),
                    backgroundColor: color.Surface.Container,
                    borderRadius: toRem(16),
                    padding: `${toRem(4)} ${toRem(8)}`,
                    border: `${toRem(1)} solid ${color.Surface.ContainerLine}`,
                    boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)',
                    marginTop: toRem(4),
                  }}
                >
                  <Box
                    as="button"
                    onClick={handleAvatarClick}
                    style={{
                      background: 'none',
                      border: 'none',
                      padding: toRem(4),
                      cursor: 'pointer',
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                      borderRadius: toRem(8),
                    }}
                  >
                    <Icon size="50" src={Icons.Pencil} />
                  </Box>
                  {avatarUrl && (
                    <Box
                      as="button"
                      onClick={(e) => {
                        e.preventDefault();
                        e.stopPropagation();
                        handleRemoveAvatar();
                      }}
                      style={{
                        backgroundColor: color.Critical.Main,
                        borderRadius: toRem(8),
                        padding: toRem(4),
                        display: 'flex',
                        alignItems: 'center',
                        justifyContent: 'center',
                        border: 'none',
                        cursor: 'pointer',
                      }}
                    >
                      <Icon size="50" src={Icons.Cross} fill="white" />
                    </Box>
                  )}
                </Box>
              )}
            </Box>
          </Box>

          {/* Profile Info Section - matches UserRoomProfile gradient section */}
          <Box
            direction="Column"
            gap="400"
            alignItems="Center"
            style={{
              padding: config.space.S400,
              paddingTop: `calc(${config.space.S400} + ${toRem(36)})`,
              marginTop: toRem(-36),
              background: previewGradient,
              textAlign: 'center',
            }}
          >
            {/* Display Name with Color Picker */}
            <Box alignItems="Center" gap="200" justifyContent="Center">
              <HexColorPickerPopOut
                picker={
                  <Box direction="Column" gap="200">
                    <HexColorPicker color={localColor} onChange={setLocalColor} />
                    <Box gap="100" alignItems="Center">
                      <Input
                        size="300"
                        variant="Secondary"
                        style={{ width: toRem(100) }}
                        value={localColor}
                        onChange={(e) => {
                          setLocalColor(e.target.value);
                          setColorError(undefined);
                        }}
                      />
                      <Button
                        size="300"
                        variant="Primary"
                        fill="Solid"
                        radii="300"
                        onClick={handleColorSave}
                        disabled={savingColor}
                      >
                        <Text size="B300">{savingColor ? 'Saving...' : 'Save'}</Text>
                      </Button>
                    </Box>
                    {colorError && (
                      <Text size="T200" style={{ color: color.Critical.Main }}>
                        {colorError}
                      </Text>
                    )}
                  </Box>
                }
                onRemove={userColor ? handleColorRemove : undefined}
              >
                {(onOpen) => (
                  <Box
                    as="button"
                    onClick={onOpen}
                    disabled={savingColor}
                    style={{
                      width: toRem(24),
                      height: toRem(24),
                      borderRadius: toRem(6),
                      backgroundColor: userColor ?? localColor,
                      border: 'none',
                      cursor: 'pointer',
                      flexShrink: 0,
                    }}
                  />
                )}
              </HexColorPickerPopOut>
              {isEditingName ? (
                <Input
                  autoFocus
                  value={editedName}
                  onChange={(e) => setEditedName(e.target.value)}
                  onKeyDown={handleNameKeyDown}
                  onBlur={handleNameSave}
                  variant="Background"
                  size="400"
                  disabled={savingName}
                  style={{
                    fontSize: 'var(--token.font-size.H400)',
                    fontWeight: 'var(--token.font-weight.H400)',
                    padding: `${toRem(4)} ${toRem(8)}`,
                    textAlign: 'center',
                  }}
                />
              ) : (
                <Box
                  as="button"
                  onClick={() => {
                    setEditedName(profile.displayName || getMxIdLocalPart(userId) || userId);
                    setIsEditingName(true);
                  }}
                  onMouseEnter={() => setHoveredArea('name')}
                  onMouseLeave={() => setHoveredArea(null)}
                  style={{
                    border: 'none',
                    background: 'none',
                    cursor: 'pointer',
                    padding: `${toRem(4)} ${toRem(8)}`,
                    margin: `${toRem(-4)} ${toRem(-8)}`,
                    position: 'relative',
                  }}
                >
                  <Text
                    size="H4"
                    className={classNames(BreakWord, LineClamp3)}
                    title={profile.displayName || getMxIdLocalPart(userId)}
                    style={{ color: previewProfileColor, textShadow: previewTextShadow }}
                  >
                    {profile.displayName || getMxIdLocalPart(userId) || userId}
                  </Text>
                  {hoveredArea === 'name' && (
                    <Box
                      style={{
                        position: 'absolute',
                        top: 0,
                        right: toRem(-32),
                        backgroundColor: color.Surface.Container,
                        borderRadius: toRem(20),
                        padding: toRem(6),
                        display: 'flex',
                        alignItems: 'center',
                        justifyContent: 'center',
                        pointerEvents: 'none',
                        border: `${toRem(1)} solid ${color.Surface.ContainerLine}`,
                      }}
                    >
                      <Icon size="50" src={Icons.Pencil} />
                    </Box>
                  )}
                </Box>
              )}
            </Box>
            
            {/* Username */}
            <Text
              size="T200"
              className={BreakWord}
              title={userId}
              style={{ color: previewProfileColor, textShadow: previewTextShadow }}
            >
              {userId}
            </Text>
            
            {/* Status Pill - Editable */}
            <Box
              onMouseEnter={() => setHoveredArea('status')}
              onMouseLeave={() => setHoveredArea(null)}
              style={{
                backgroundColor: previewPillBgColor || color.Surface.Container,
                border: previewPillBgColor ? 'none' : `${toRem(1)} solid ${color.Surface.ContainerLine}`,
                padding: `${toRem(6)} ${toRem(10)}`,
                borderRadius: toRem(16),
                maxWidth: toRem(250),
                cursor: 'pointer',
              }}
            >
              {isEditingStatus ? (
                <Input
                  style={{ width: toRem(150), minWidth: toRem(100), textAlign: 'center' }}
                  variant="Background"
                  size="300"
                  autoFocus
                  value={editedStatus}
                  onChange={(e: ChangeEvent<HTMLInputElement>) =>
                    setEditedStatus(e.target.value)
                  }
                  onKeyDown={handleStatusKeyDown}
                  onBlur={handleStatusSave}
                  disabled={savingStatus}
                  placeholder="Set a custom status..."
                />
              ) : (
                <Box
                  style={{
                    display: 'flex',
                    alignItems: 'center',
                    gap: toRem(4),
                    justifyContent: 'center',
                  }}
                >
                  <Box
                    as="button"
                    onClick={() => {
                      setEditedStatus(presence?.status || '');
                      setIsEditingStatus(true);
                    }}
                    style={{
                      background: 'none',
                      border: 'none',
                      padding: 0,
                      cursor: 'pointer',
                      display: 'flex',
                      alignItems: 'center',
                    }}
                  >
                    <Text
                      size="T300"
                      className={BreakWord}
                      style={{
                        fontStyle: presence?.status ? 'normal' : 'italic',
                        color: previewPillBgColor ? getContrastingTextColor(previewPillBgColor) : undefined,
                      }}
                    >
                      {presence?.status || 'Click to set a custom status...'}</Text>
                  </Box>
                  {presence?.status && hoveredArea === 'status' && (
                    <>
                      <Icon size="50" src={Icons.Pencil} style={{ color: previewPillBgColor ? getContrastingTextColor(previewPillBgColor) : undefined }} />
                      <Box
                        as="button"
                        onClick={(e) => {
                          e.preventDefault();
                          e.stopPropagation();
                          handleRemoveStatus();
                        }}
                        style={{
                          backgroundColor: color.Critical.Main,
                          borderRadius: toRem(8),
                          padding: toRem(2),
                          display: 'flex',
                          alignItems: 'center',
                          justifyContent: 'center',
                          cursor: 'pointer',
                          border: 'none',
                        }}
                      >
                        <Icon size="50" src={Icons.Cross} fill="white" />
                      </Box>
                    </>
                  )}
                </Box>
              )}
            </Box>
            
            {/* Chips Row - Placeholder chips */}
            <Box alignItems="Center" gap="200" wrap="Wrap" justifyContent="Center">
              <Box
                style={{
                  backgroundColor: previewPillBgColor || color.Surface.Container,
                  border: previewPillBgColor ? 'none' : `${toRem(1)} solid ${color.Surface.ContainerLine}`,
                  padding: `${toRem(4)} ${toRem(8)}`,
                  borderRadius: toRem(16),
                }}
              >
                <Text 
                  size="B300" 
                  style={{
                    color: previewPillBgColor ? getContrastingTextColor(previewPillBgColor) : undefined,
                  }}
                >
                  ruv.wtf
                </Text>
              </Box>
              <Box
                style={{
                  backgroundColor: previewPillBgColor || color.Surface.Container,
                  border: previewPillBgColor ? 'none' : `${toRem(1)} solid ${color.Surface.ContainerLine}`,
                  padding: `${toRem(4)} ${toRem(8)}`,
                  borderRadius: toRem(16),
                }}
              >
                <Text 
                  size="B300"
                  style={{
                    color: previewPillBgColor ? getContrastingTextColor(previewPillBgColor) : undefined,
                  }}
                >
                  Share
                </Text>
              </Box>
              <Box
                style={{
                  backgroundColor: previewPillBgColor || color.Surface.Container,
                  border: previewPillBgColor ? 'none' : `${toRem(1)} solid ${color.Surface.ContainerLine}`,
                  padding: `${toRem(4)} ${toRem(8)}`,
                  borderRadius: toRem(16),
                }}
              >
                <Text 
                  size="B300"
                  style={{
                    color: previewPillBgColor ? getContrastingTextColor(previewPillBgColor) : undefined,
                  }}
                >
                  Admin
                </Text>
              </Box>
            </Box>
          </Box>
        </Box>

      {/* Profile Style Settings */}
      <Box
        direction="Column"
        gap="200"
        style={{
          padding: config.space.S300,
          border: `${toRem(1)} solid ${color.Surface.ContainerLine}`,
          borderRadius: toRem(8),
          width: '100%',
        }}
      >
        <Text size="H6">Profile Style</Text>
        
        {/* Avatar Border Color */}
        <Box direction="Column" gap="100">
          <Text size="T300">Avatar Border Color</Text>
          <Box gap="200" alignItems="Center" wrap="Wrap">
            <RgbaColorPicker color={localBorderColor} onChange={(c) => { setLocalBorderColor(c); setEditingBorder(true); }} />
            <Box direction="Column" gap="100">
              <Text size="T200" style={{ opacity: 0.7 }}>
                Preview: {rgbaToHex(localBorderColor)}
              </Text>
              <Box
                style={{
                  width: toRem(48),
                  height: toRem(48),
                  borderRadius: '50%',
                  border: `${toRem(4)} solid ${rgbaToHex(localBorderColor)}`,
                  backgroundColor: color.Surface.Container,
                }}
              />
              <Box gap="100">
                <Button
                  size="300"
                  variant="Primary"
                  fill="Solid"
                  radii="300"
                  onClick={handleBorderColorSave}
                  disabled={savingStyle}
                >
                  <Text size="B300">Save</Text>
                </Button>
                {profileStyle.avatarBorderColor && (
                  <Button
                    size="300"
                    variant="Critical"
                    fill="Soft"
                    radii="300"
                    onClick={handleBorderColorRemove}
                    disabled={savingStyle}
                  >
                    <Text size="B300">Remove</Text>
                  </Button>
                )}
              </Box>
            </Box>
          </Box>
        </Box>

        {/* Profile Gradient */}
        <Box direction="Column" gap="100">
          <Text size="T300">Profile Card Gradient</Text>
          <Box gap="200" alignItems="Start" wrap="Wrap">
            <Box direction="Column" gap="100">
              <Text size="T200">Start Color</Text>
              <RgbaColorPicker color={localGradientStart} onChange={(c) => { setLocalGradientStart(c); setEditingGradient(true); }} />
            </Box>
            <Box direction="Column" gap="100">
              <Text size="T200">End Color</Text>
              <RgbaColorPicker color={localGradientStop} onChange={(c) => { setLocalGradientStop(c); setEditingGradient(true); }} />
            </Box>
            <Box direction="Column" gap="100">
              <Text size="T200">Direction</Text>
              <AngleSelector
                value={localGradientDirection}
                onChange={(deg) => { setLocalGradientDirection(deg); setEditingGradient(true); }}
              />
              <Box
                style={{
                  width: toRem(100),
                  height: toRem(60),
                  borderRadius: toRem(8),
                  background: `linear-gradient(${localGradientDirection}deg, ${rgbaToHex(localGradientStart)}, ${rgbaToHex(localGradientStop)})`,
                  border: `${toRem(1)} solid ${color.Surface.ContainerLine}`,
                }}
              />
              <Box gap="100">
                <Button
                  size="300"
                  variant="Primary"
                  fill="Solid"
                  radii="300"
                  onClick={handleGradientSave}
                  disabled={savingStyle}
                >
                  <Text size="B300">Save</Text>
                </Button>
                {profileStyle.gradient && (
                  <Button
                    size="300"
                    variant="Critical"
                    fill="Soft"
                    radii="300"
                    onClick={handleGradientRemove}
                    disabled={savingStyle}
                  >
                    <Text size="B300">Remove</Text>
                  </Button>
                )}
              </Box>
            </Box>
          </Box>
        </Box>

        {styleError && (
          <Text size="T200" style={{ color: color.Critical.Main }}>{styleError}</Text>
        )}
      </Box>

      {uploadAtom && (
        <Box gap="200" direction="Column" style={{ width: '100%' }}>
          <CompactUploadCardRenderer
            uploadAtom={uploadAtom}
            onRemove={handleRemoveUpload}
            onComplete={handleUploaded}
          />
        </Box>
      )}
      {avatarUploadAtom && (
        <Box gap="200" direction="Column" style={{ width: '100%' }}>
          <CompactUploadCardRenderer
            uploadAtom={avatarUploadAtom}
            onRemove={() => setAvatarFile(undefined)}
            onComplete={handleAvatarUploaded}
          />
        </Box>
      )}
      {saving && (
        <Box gap="200" alignItems="Center">
          <Spinner size="100" variant="Secondary" />
          <Text size="T200">Saving to server…</Text>
        </Box>
      )}
      {error && (
        <Text size="T200" style={{ color: color.Critical.Main }}>{error}</Text>
      )}
    </Box>
  );
}

export function Profile() {
  const mx = useMatrixClient();
  const userId = mx.getUserId()!;
  const avatarRef = useRef<HTMLDivElement>(null);
  const nameRef = useRef<HTMLDivElement>(null);

  return (
    <ProfileBanner avatarRef={avatarRef} nameRef={nameRef} />
  );
}
