import React from 'react';
import { Box, Text, as } from 'folds';
import classNames from 'classnames';
import { MatrixClient, MatrixEvent, Room } from 'matrix-js-sdk';
import * as css from './Reaction.css';
import { getHexcodeForEmoji, getShortcodeFor } from '../../plugins/emoji';
import { getMemberDisplayName } from '../../utils/room';
import { eventWithShortcode, getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
import { isStationeryTheme, useTheme } from '../../hooks/useTheme';

const MAX_STICKER_STACK = 4;

export const Reaction = as<
  'button',
  {
    mx: MatrixClient;
    count: number;
    reaction: string;
    useAuthentication?: boolean;
  }
>(({ className, mx, count, reaction, useAuthentication, ...props }, ref) => {
  const theme = useTheme();
  const stationery = isStationeryTheme(theme);
  const isCustomEmoji = reaction.startsWith('mxc://');
  const customSrc = isCustomEmoji
    ? mxcUrlToHttp(mx, reaction, useAuthentication) ?? reaction
    : undefined;

  const emoji = isCustomEmoji ? (
    <img className={css.ReactionImg} src={customSrc} alt={reaction} />
  ) : (
    <Text as="span" size="Inherit" truncate>
      {reaction}
    </Text>
  );

  // Stationery: fanned sticker stack. Everywhere else: compact emoji + count.
  if (!stationery) {
    return (
      <Box
        as="button"
        className={classNames(css.Reaction, className)}
        alignItems="Center"
        shrink="No"
        gap="200"
        data-reaction=""
        aria-label={`${reaction}, ${count}`}
        {...props}
        ref={ref}
      >
        <Text className={css.ReactionText} as="span" size="T400">
          {emoji}
        </Text>
        <Text as="span" size="T300" data-reaction-count="">
          {count}
        </Text>
      </Box>
    );
  }

  const stackCount = Math.min(Math.max(count, 1), MAX_STICKER_STACK);
  const showCount = count > 2;

  return (
    <Box
      as="button"
      className={classNames(css.Reaction, className)}
      alignItems="Center"
      shrink="No"
      gap="200"
      data-reaction=""
      data-reaction-stack={stackCount}
      aria-label={`${reaction}, ${count}`}
      {...props}
      ref={ref}
    >
      <span className={css.ReactionStack} data-reaction-stack-layer="">
        {Array.from({ length: stackCount }, (_, i) => {
          const layer = stackCount - 1 - i;
          return (
            <Text
              key={layer}
              className={css.ReactionSticker}
              as="span"
              size="T400"
              data-reaction-sticker=""
              style={{
                ['--sticker-i' as string]: layer,
                zIndex: i + 1,
              }}
              aria-hidden={i < stackCount - 1 ? true : undefined}
            >
              {isCustomEmoji ? (
                <img
                  className={css.ReactionImg}
                  src={customSrc}
                  alt={i === stackCount - 1 ? reaction : ''}
                />
              ) : (
                <Text as="span" size="Inherit" truncate>
                  {reaction}
                </Text>
              )}
            </Text>
          );
        })}
      </span>
      {showCount && (
        <Text as="span" size="T300" data-reaction-count="">
          {count}
        </Text>
      )}
    </Box>
  );
});

type ReactionTooltipMsgProps = {
  room: Room;
  reaction: string;
  events: MatrixEvent[];
};

export function ReactionTooltipMsg({ room, reaction, events }: ReactionTooltipMsgProps) {
  const shortCodeEvt = events.find(eventWithShortcode);
  const shortcode =
    shortCodeEvt?.getContent().shortcode ??
    getShortcodeFor(getHexcodeForEmoji(reaction)) ??
    reaction;
  const names = events.map(
    (ev: MatrixEvent) =>
      getMemberDisplayName(room, ev.getSender() ?? 'Unknown') ??
      getMxIdLocalPart(ev.getSender() ?? 'Unknown') ??
      'Unknown'
  );

  return (
    <>
      {names.length === 1 && <b>{names[0]}</b>}
      {names.length === 2 && (
        <>
          <b>{names[0]}</b>
          <Text as="span" size="Inherit" priority="300">
            {' and '}
          </Text>
          <b>{names[1]}</b>
        </>
      )}
      {names.length === 3 && (
        <>
          <b>{names[0]}</b>
          <Text as="span" size="Inherit" priority="300">
            {', '}
          </Text>
          <b>{names[1]}</b>
          <Text as="span" size="Inherit" priority="300">
            {' and '}
          </Text>
          <b>{names[2]}</b>
        </>
      )}
      {names.length > 3 && (
        <>
          <b>{names[0]}</b>
          <Text as="span" size="Inherit" priority="300">
            {', '}
          </Text>
          <b>{names[1]}</b>
          <Text as="span" size="Inherit" priority="300">
            {', '}
          </Text>
          <b>{names[2]}</b>
          <Text as="span" size="Inherit" priority="300">
            {' and '}
          </Text>
          <b>{names.length - 3} others</b>
        </>
      )}
      <Text as="span" size="Inherit" priority="300">
        {' reacted with '}
      </Text>
      :<b>{shortcode}</b>:
    </>
  );
}
