import React, { useState } from 'react';
import type { Room } from 'matrix-js-sdk';
import { Icon, IconButton, Icons, PopOut, RectCords, Tooltip, TooltipProvider, Text } from 'folds';
import FocusTrap from 'focus-trap-react';
import { useTranslation } from 'react-i18next';
import type { BotPreset } from './catalog';
import { BotShellMenu } from './BotShellMenu';
import { BackRouteHandler } from '../../components/BackRouteHandler';
import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize';
import { stopPropagation } from '../../utils/keyboard';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
import { mxcUrlToHttp } from '../../utils/matrix';
import * as css from './BotShell.css';

type BotShellHeroProps = {
  preset: BotPreset;
  room: Room;
};

// Initial for the avatar block. Prefer the human name's first character
// (matches mockup BOT.name = «build-bot» → «B»); fall back to the mxid
// localpart, then to «?» when neither is usable. The previous «T» literal
// hardcoded the Telegram preset and fails the moment a second bot ships.
const heroInitial = (preset: BotPreset): string => {
  const fromName = preset.name.trim().charAt(0);
  if (fromName) return fromName.toUpperCase();
  const local = preset.mxid.split(':')[0].replace('@', '');
  return local.charAt(0).toUpperCase() || '?';
};

export function BotShellHero({ preset, room }: BotShellHeroProps) {
  const { t } = useTranslation();
  const mx = useMatrixClient();
  const useAuthentication = useMediaAuthentication();
  const screenSize = useScreenSizeContext();
  const isMobile = screenSize === ScreenSize.Mobile;
  const [menuAnchor, setMenuAnchor] = useState<RectCords>();

  // Standard Matrix avatar resolution. The bot user's profile carries the
  // canonical `avatar_url` (set server-side by the bridge or homeserver
  // admin); every Matrix client reads the same source. We pull it via the
  // bot's RoomMember in this DM rather than `mx.getUser()` because the
  // member event in this room is guaranteed to be loaded by the time we
  // render — we wouldn't be on `/bots/<id>` otherwise — and avoids any
  // edge case where `mx.getUser()` returns a stale or missing entry.
  const avatarMxc = room.getMember(preset.mxid)?.getMxcAvatarUrl();
  const avatarUrl = avatarMxc
    ? mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined
    : undefined;

  const handleOpenMenu: React.MouseEventHandler<HTMLButtonElement> = (evt) => {
    setMenuAnchor(evt.currentTarget.getBoundingClientRect());
  };

  // Operator override from /config.json wins; otherwise fall back to the
  // localized `Bots.description.<id>` key. Empty string suppresses the
  // line entirely so a missing translation doesn't ship the key.
  const description = t(`Bots.description.${preset.id}`, {
    defaultValue: preset.description ?? '',
  });
  // Mobile-only one-liner. Falls back to the long description when no
  // short variant is configured — better to truncate the long one than
  // render nothing in the chat-header band.
  const descriptionShort = t(`Bots.description_short.${preset.id}`, {
    defaultValue: description,
  });
  const initial = heroInitial(preset);

  return (
    <header className={css.Hero}>
      <div className={css.HeroInner}>
        {/* Mobile back chevron — bypasses Cinny's standard RoomViewHeader
         * (which BotShell deliberately doesn't mount), so the user retains
         * the «walk up the route tree» affordance the rest of the client
         * provides on phone. Desktop relies on the sidebar to navigate. */}
        {isMobile && (
          <BackRouteHandler>
            {(onBack) => (
              <IconButton
                className={css.HeroBack}
                fill="None"
                onClick={onBack}
                aria-label={t('Room.close')}
              >
                <Icon src={Icons.ChevronLeft} />
              </IconButton>
            )}
          </BackRouteHandler>
        )}
        <div className={css.HeroAvatar} aria-hidden="true">
          {avatarUrl ? <img className={css.HeroAvatarImg} src={avatarUrl} alt="" /> : initial}
        </div>
        <div className={css.HeroBody}>
          <div className={css.HeroTitleRow}>
            <span className={css.HeroName}>{preset.name}</span>
            <span className={css.HeroHandle}>{preset.mxid}</span>
          </div>
          {description ? <p className={css.HeroDescription}>{description}</p> : null}
          {descriptionShort ? <p className={css.HeroDescriptionShort}>{descriptionShort}</p> : null}
        </div>

        {/* «О боте» lives INSIDE the widget body now (next to login/refresh/
         * logout cards) — see apps/widget-telegram/src/App.tsx. The hero
         * keeps only the standard three-dots menu trigger so its trailing
         * actions match the rest of the chat headers in the project. */}
        <TooltipProvider
          position="Bottom"
          align="End"
          offset={4}
          tooltip={
            <Tooltip>
              <Text>{t('Bots.more_options')}</Text>
            </Tooltip>
          }
        >
          {(triggerRef) => (
            <IconButton
              fill="None"
              ref={triggerRef}
              onClick={handleOpenMenu}
              aria-pressed={!!menuAnchor}
              aria-label={t('Bots.more_options')}
            >
              <Icon src={Icons.VerticalDots} filled={!!menuAnchor} />
            </IconButton>
          )}
        </TooltipProvider>
      </div>

      <PopOut
        anchor={menuAnchor}
        position="Bottom"
        align="End"
        content={
          <FocusTrap
            focusTrapOptions={{
              initialFocus: false,
              returnFocusOnDeactivate: false,
              onDeactivate: () => setMenuAnchor(undefined),
              clickOutsideDeactivates: true,
              isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown',
              isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp',
              escapeDeactivates: stopPropagation,
            }}
          >
            <BotShellMenu room={room} requestClose={() => setMenuAnchor(undefined)} />
          </FocusTrap>
        }
      />
    </header>
  );
}
