import React from 'react';
import { Avatar, Box, Icon, IconButton, Icons, Text, Tooltip, TooltipProvider } from 'folds';
import classNames from 'classnames';
import { useTranslation } from 'react-i18next';
import { Room } from 'matrix-js-sdk';
import { useSetAtom } from 'jotai';
import { useNavigate } from 'react-router-dom';
import * as css from './styles.css';
import { ContainerColor } from '../../styles/ContainerColor.css';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
import { UserAvatar } from '../../components/user-avatar';
import { getMemberAvatarMxc, getMemberDisplayName } from '../../utils/room';
import { getCanonicalAliasOrRoomId, getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
import { useSwitchOrStartDmCall } from '../../hooks/useSwitchOrStartDmCall';
import { getDirectRoomPath } from '../../pages/pathUtils';
import { IncomingCall, incomingCallsAtom } from '../../state/incomingCalls';
import { getIncomingCallKey } from '../../utils/rtcNotification';
import { CallPhoneDownIcon, CallPhoneIcon } from './callIcons';

const DECLINE_RETRY_DELAY_MS = 500;

type IncomingCallStripProps = {
  call: IncomingCall;
  room: Room;
};
export function IncomingCallStrip({ call, room }: IncomingCallStripProps) {
  const { t } = useTranslation();
  const mx = useMatrixClient();
  const navigate = useNavigate();
  const useAuthentication = useMediaAuthentication();
  const switchOrStartDmCall = useSwitchOrStartDmCall();
  const setIncoming = useSetAtom(incomingCallsAtom);

  const senderId = call.notifEvent.getSender();
  const displayName =
    (senderId && getMemberDisplayName(room, senderId)) ||
    (senderId && getMxIdLocalPart(senderId)) ||
    senderId ||
    t('Call.unknown_caller');
  const avatarMxc = senderId ? getMemberAvatarMxc(room, senderId) : undefined;
  const avatarUrl = avatarMxc
    ? mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined
    : undefined;

  const callKey = getIncomingCallKey(call.callId, call.roomId);

  const handleAnswer = () => {
    // Mirror the native CallStyle Answer path (usePushNotifications
    // pushNotificationActionPerformed handler): in-app strip Answer is the
    // same semantic action — switch to the call room — so it should not
    // grow the back stack either.
    navigate(getDirectRoomPath(getCanonicalAliasOrRoomId(mx, call.roomId)), { replace: true });
    switchOrStartDmCall(call.roomId)
      .then(() => {
        const evId = call.notifEvent.getId();
        if (evId) {
          setIncoming({ type: 'REMOVE_BY_NOTIF_ID', notifEventId: evId });
          return;
        }
        setIncoming({ type: 'REMOVE', key: callKey });
      })
      .catch((err: unknown) => {
        // eslint-disable-next-line no-console
        console.warn('[call] strip answer switch/start failed', err);
      });
  };

  const handleDecline = async () => {
    setIncoming({ type: 'REMOVE', key: callKey });
    const evId = call.notifEvent.getId();
    if (!evId) return;
    try {
      await mx.sendRtcDecline(call.roomId, evId);
    } catch (err) {
      await new Promise((resolve) => {
        setTimeout(resolve, DECLINE_RETRY_DELAY_MS);
      });
      try {
        await mx.sendRtcDecline(call.roomId, evId);
      } catch (retryErr) {
        // eslint-disable-next-line no-console
        console.warn('[call] sendRtcDecline failed after retry', retryErr);
      }
    }
  };

  return (
    <Box
      className={classNames(css.RingRow, ContainerColor({ variant: 'Background' }))}
      shrink="No"
      direction="Row"
      alignItems="Center"
      gap="500"
    >
      <Avatar className={css.RingAvatar}>
        <UserAvatar
          userId={senderId ?? ''}
          src={avatarUrl}
          alt={displayName}
          renderFallback={() => <Icon size="400" src={Icons.User} filled />}
        />
      </Avatar>
      <Box grow="Yes" direction="Column" gap="100">
        <Text size="H4" truncate>
          {displayName}
        </Text>
        <Text size="T200" priority="300">
          {t('Call.incoming')}
        </Text>
      </Box>
      <Box shrink="No" alignItems="Center" gap="300">
        <TooltipProvider
          position="Top"
          tooltip={
            <Tooltip>
              <Text size="T200">{t('Call.decline')}</Text>
            </Tooltip>
          }
        >
          {(anchorRef) => (
            <IconButton
              ref={anchorRef}
              variant="Critical"
              fill="Soft"
              radii="Pill"
              size="500"
              onClick={handleDecline}
              aria-label={t('Call.decline')}
            >
              <Icon size="300" src={CallPhoneDownIcon} />
            </IconButton>
          )}
        </TooltipProvider>
        <TooltipProvider
          position="Top"
          tooltip={
            <Tooltip>
              <Text size="T200">{t('Call.answer')}</Text>
            </Tooltip>
          }
        >
          {(anchorRef) => (
            <IconButton
              ref={anchorRef}
              variant="Success"
              fill="Soft"
              radii="Pill"
              size="500"
              onClick={handleAnswer}
              aria-label={t('Call.answer')}
            >
              <Icon size="300" src={CallPhoneIcon} />
            </IconButton>
          )}
        </TooltipProvider>
      </Box>
    </Box>
  );
}
