import { Box, color, config, Icon, Icons, IconSrc, Spinner, toRem } from 'folds';
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { NotificationMode } from '../../../hooks/useNotificationMode';
import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';

export const useNotificationModes = (): NotificationMode[] =>
  useMemo(() => [NotificationMode.NotifyLoud, NotificationMode.Notify, NotificationMode.OFF], []);

// Mirror the per-room bell language (getRoomNotificationModeIcon): loud = ring,
// silent = ping, off = mute.
const useNotificationModeIcon = (): Record<NotificationMode, IconSrc> =>
  useMemo(
    () => ({
      [NotificationMode.NotifyLoud]: Icons.BellRing,
      [NotificationMode.Notify]: Icons.BellPing,
      [NotificationMode.OFF]: Icons.BellMute,
    }),
    []
  );

const useNotificationModeStr = (): Record<NotificationMode, string> => {
  const { t } = useTranslation();
  return useMemo(
    () => ({
      [NotificationMode.OFF]: t('Settings.notif_disable'),
      [NotificationMode.Notify]: t('Settings.notif_silent'),
      [NotificationMode.NotifyLoud]: t('Settings.notif_loud'),
    }),
    [t]
  );
};

type NotificationModeSwitcherProps = {
  // The group's consolidated mode (loudest member, factoring server-disabled
  // rules). Controlled by the parent — the switcher no longer reads a rule.
  selectedMode: NotificationMode;
  onChange: (mode: NotificationMode) => Promise<void>;
};
export function NotificationModeSwitcher({
  selectedMode,
  onChange,
}: NotificationModeSwitcherProps) {
  const modes = useNotificationModes();
  const modeToIcon = useNotificationModeIcon();
  const modeToStr = useNotificationModeStr();
  const [changeState, change] = useAsyncCallback(onChange);
  const changing = changeState.status === AsyncStatus.Loading;

  return (
    <Box
      shrink="No"
      alignItems="Center"
      gap="0"
      style={{
        position: 'relative',
        padding: toRem(2),
        borderRadius: config.radii.Pill,
        backgroundColor: color.SurfaceVariant.Container,
        opacity: changing ? 0.6 : undefined,
      }}
    >
      {modes.map((mode) => {
        const selected = mode === selectedMode;
        return (
          <button
            key={mode}
            type="button"
            aria-label={modeToStr[mode]}
            aria-pressed={selected}
            title={modeToStr[mode]}
            disabled={changing}
            onClick={() => change(mode)}
            style={{
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
              width: toRem(32),
              height: toRem(28),
              border: 'none',
              cursor: changing ? 'default' : 'pointer',
              borderRadius: config.radii.Pill,
              backgroundColor: selected ? color.Primary.Main : 'transparent',
              color: selected ? color.Primary.OnMain : color.SurfaceVariant.OnContainer,
            }}
          >
            <Icon
              size="100"
              src={modeToIcon[mode]}
              filled={selected}
              style={{ color: 'inherit' }}
            />
          </button>
        );
      })}
      {changing && (
        <Box alignItems="Center" justifyContent="Center" style={{ position: 'absolute', inset: 0 }}>
          <Spinner variant="Secondary" size="300" />
        </Box>
      )}
    </Box>
  );
}
