import React, { useCallback, useState } from 'react';
import { Avatar, Box, Button, Spinner, Text, as } from 'folds';
import { Room } from 'matrix-js-sdk';
import { Trans, useTranslation } from 'react-i18next';
import { IRoomCreateContent, Membership, StateEvent } from '../../../types/matrix/room';
import { getMemberDisplayName, getStateEvent } from '../../utils/room';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
import { timeDayMonthYear, timeHourMinute } from '../../utils/time';
import { useRoomNavigate } from '../../hooks/useRoomNavigate';
import { RoomAvatar } from '../room-avatar';
import { nameInitials } from '../../utils/common';
import { useRoomAvatar, useRoomName, useRoomTopic } from '../../hooks/useRoomMeta';
import { useIsOneOnOne } from '../../hooks/useRoom';
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
import { InviteUserPrompt } from '../invite-user-prompt';

export type RoomIntroProps = {
  room: Room;
};

export const RoomIntro = as<'div', RoomIntroProps>(({ room, ...props }, ref) => {
  const { t } = useTranslation();
  const mx = useMatrixClient();
  const useAuthentication = useMediaAuthentication();
  const { navigateRoom } = useRoomNavigate();
  // Match RoomViewHeader's peer-avatar logic — pull the fallback only when the
  // room is strictly 1:1, not when it carries an `m.direct` flag. Bridged
  // Telegram 1:1s and just-promoted self-DMs both lack the flag but have
  // member-count = 2, so this picks them up correctly.
  const isOneOnOne = useIsOneOnOne();
  const [invitePrompt, setInvitePrompt] = useState(false);

  const createEvent = getStateEvent(room, StateEvent.RoomCreate);
  const avatarMxc = useRoomAvatar(room, isOneOnOne);
  const name = useRoomName(room);
  const topic = useRoomTopic(room);
  const avatarHttpUrl = avatarMxc ? mxcUrlToHttp(mx, avatarMxc, useAuthentication) : undefined;

  const createContent = createEvent?.getContent<IRoomCreateContent>();
  const ts = createEvent?.getTs();
  const creatorId = createEvent?.getSender();
  const creatorName =
    creatorId && (getMemberDisplayName(room, creatorId) ?? getMxIdLocalPart(creatorId));
  const prevRoomId = createContent?.predecessor?.room_id;

  const [prevRoomState, joinPrevRoom] = useAsyncCallback(
    useCallback(async (roomId: string) => mx.joinRoom(roomId), [mx])
  );

  return (
    <Box direction="Column" grow="Yes" gap="500" {...props} ref={ref}>
      <Box>
        <Avatar size="500">
          <RoomAvatar
            roomId={room.roomId}
            src={avatarHttpUrl ?? undefined}
            alt={name}
            renderFallback={() => <Text size="H2">{nameInitials(name)}</Text>}
          />
        </Avatar>
      </Box>
      <Box direction="Column" gap="300">
        <Box direction="Column" gap="100">
          <Text size="H3" priority="500">
            {name}
          </Text>
          <Text size="T400" priority="400">
            {typeof topic === 'string' ? topic : t('Room.conversation_beginning')}
          </Text>
          {creatorName && ts && (
            <Text size="T200" priority="300">
              <Trans
                i18nKey="Room.created_by"
                values={{
                  creator: creatorName,
                  date: timeDayMonthYear(ts),
                  time: timeHourMinute(ts),
                }}
                components={{ bold: <b /> }}
              />
            </Text>
          )}
        </Box>
        <Box gap="200" wrap="Wrap">
          <Button onClick={() => setInvitePrompt(true)} variant="Secondary" size="300" radii="300">
            <Text size="B300">{t('Room.invite_member')}</Text>
          </Button>

          {invitePrompt && (
            <InviteUserPrompt room={room} requestClose={() => setInvitePrompt(false)} />
          )}
          {typeof prevRoomId === 'string' &&
            (mx.getRoom(prevRoomId)?.getMyMembership() === Membership.Join ? (
              <Button
                onClick={() => navigateRoom(prevRoomId, createContent?.predecessor?.event_id)}
                variant="Success"
                size="300"
                fill="Soft"
                radii="300"
              >
                <Text size="B300">{t('Room.open_old_room')}</Text>
              </Button>
            ) : (
              <Button
                onClick={() => joinPrevRoom(prevRoomId)}
                variant="Secondary"
                size="300"
                fill="Soft"
                radii="300"
                disabled={prevRoomState.status === AsyncStatus.Loading}
                after={
                  prevRoomState.status === AsyncStatus.Loading ? (
                    <Spinner size="50" variant="Secondary" fill="Soft" />
                  ) : undefined
                }
              >
                <Text size="B300">{t('Room.join_old_room')}</Text>
              </Button>
            ))}
        </Box>
      </Box>
    </Box>
  );
});
