import { type FC } from 'react';

import { useCallStateHooks } from '@stream-io/video-react-sdk';
import {
  IconCamera,
  IconExclamationCircle,
  IconMicrophone,
} from '@material-hu/icons/tabler';
import MenuItem from '@material-hu/mui/MenuItem';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuStateCard from '@material-hu/components/composed-components/StateCard';
import HuPills from '@material-hu/components/design-system/Pills';

import { DeviceType } from 'src/types/stream';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { FormSelect } from 'src/components/FormInputs';

import AudioVisualizer from './AudioVisualizer';

const FormDeviceControls: FC = () => {
  const { useMicrophoneState, useCameraState } = useCallStateHooks();
  const {
    camera,
    devices: dcam,
    hasBrowserPermission: hasPermissionCamera,
  } = useCameraState();
  const {
    microphone,
    devices: dmic,
    hasBrowserPermission: hasPermissionMicrophone,
  } = useMicrophoneState();
  const { t } = useLokaliseTranslation('livestream');

  const optionsCamera = dcam?.map(opt => ({
    value: opt.deviceId,
    label: opt.label,
  }));

  const optionsMicrophone = dmic?.map(opt => ({
    value: opt.deviceId,
    label: opt.label,
  }));

  const handleChangeDevice = async (
    option: { value: string; label: string },
    deviceType: DeviceType,
  ) => {
    if (deviceType === DeviceType.CAMERA) {
      const preferredDevice = dcam?.find(d => d.deviceId === option.value);
      if (preferredDevice) await camera.select(preferredDevice.deviceId);
    } else {
      const preferredDevice = dmic?.find(d => d.deviceId === option.value);
      if (preferredDevice) await microphone.select(preferredDevice.deviceId);
    }
  };

  const renderMenuItem = (
    option: { value: string; label: string },
    deviceType: DeviceType,
  ): JSX.Element => (
    <MenuItem
      key={option.value}
      value={option.value}
      onClick={() => handleChangeDevice(option, deviceType)}
    >
      <Typography
        sx={{
          whiteSpace: 'nowrap',
          overflow: 'hidden',
          textOverflow: 'ellipsis',
          WebkitLineClamp: 1,
          WebkitBoxOrient: 'vertical',
        }}
      >
        {option.label}
      </Typography>
    </MenuItem>
  );

  const renderItemsCamera = () =>
    optionsCamera?.map(option => renderMenuItem(option, DeviceType.CAMERA));

  const renderItemsMicrophone = () =>
    optionsMicrophone?.map(option =>
      renderMenuItem(option, DeviceType.MICROPHONE),
    );

  if (!hasPermissionCamera && !hasPermissionMicrophone) {
    return (
      <HuStateCard
        sx={{ border: 'none' }}
        slotProps={{
          avatar: {
            Icon: IconExclamationCircle,
            size: 'medium',
            color: 'warning',
          },
          title: {
            title: t('NO_PERMISSION_TITLE'),
            description: t('NO_PERMISSION_DESCRIPTION'),
          },
        }}
      />
    );
  }

  return (
    <>
      <Typography
        variant="globalXS"
        color="new.text.neutral.lighter"
      >
        {t('CAMERA_CONTROLS_DESCRIPTION')}
      </Typography>
      <Stack sx={{ gap: theme => theme.spacing(2) }}>
        <Stack
          sx={{
            flexDirection: 'row',
            alignItems: 'center',
            gap: theme => theme.spacing(2),
          }}
        >
          <IconCamera />
          {hasPermissionCamera && !!optionsCamera?.length && (
            <FormSelect
              variant="outlined"
              name="camera"
              renderMenuItems={renderItemsCamera}
              defaultValue={optionsCamera[0].value}
              options={optionsCamera}
              MenuProps={{
                PaperProps: {
                  style: {
                    maxWidth: '650px',
                  },
                },
              }}
            />
          )}
          {!hasPermissionCamera && (
            <HuPills
              label={t('NO_PERMISSION_ALERT')}
              type="warning"
            />
          )}
        </Stack>
        <Stack
          sx={{
            flexDirection: 'row',
            alignItems: 'center',
            gap: theme => theme.spacing(2),
          }}
        >
          <IconMicrophone />
          {hasPermissionMicrophone && !!optionsMicrophone?.length && (
            <>
              <FormSelect
                variant="outlined"
                name="microphone"
                renderMenuItems={renderItemsMicrophone}
                defaultValue={optionsMicrophone[0].value}
                options={optionsMicrophone}
                MenuProps={{
                  PaperProps: {
                    style: {
                      maxWidth: '650px',
                    },
                  },
                }}
                formControlProps={{
                  sx: {
                    width: 'initial',
                  },
                }}
              />
              <AudioVisualizer />
            </>
          )}
          {!hasPermissionMicrophone && (
            <HuPills
              label={t('NO_PERMISSION_ALERT')}
              type="warning"
            />
          )}
        </Stack>
      </Stack>
    </>
  );
};

export default FormDeviceControls;
