import React, { FormEventHandler, useCallback } from 'react';
import { Box, Button, color, Input, Spinner, Text } from 'folds';
import { MatrixError } from 'matrix-js-sdk';
import { SequenceCard } from '../../../components/sequence-card';
import { SequenceCardStyle } from '../../room-settings/styles.css';
import { SettingTile } from '../../../components/setting-tile';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { useRoom } from '../../../hooks/useRoom';
import { StateEvent } from '../../../../types/matrix/room';
import { sendStateEvent } from '../../../utils/room';
import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
import { useStateEvent } from '../../../hooks/useStateEvent';
import { RoomPermissionsAPI } from '../../../hooks/useRoomPermissions';

export type VoiceLimitContent = {
  max_users?: number;
};

type RoomVoiceLimitProps = {
  permissions: RoomPermissionsAPI;
};
export function RoomVoiceLimit({ permissions }: RoomVoiceLimitProps) {
  const mx = useMatrixClient();
  const room = useRoom();

  const canEdit = permissions.stateEvent(StateEvent.LotusVoiceLimit, mx.getSafeUserId());

  const limitEvent = useStateEvent(room, StateEvent.LotusVoiceLimit);
  const maxUsers = limitEvent?.getContent<VoiceLimitContent>().max_users ?? 0;

  const [submitState, submit] = useAsyncCallback(
    useCallback(
      async (value: number) => {
        const content: VoiceLimitContent = value > 0 ? { max_users: value } : {};
        await sendStateEvent(mx, room.roomId, StateEvent.LotusVoiceLimit, content);
      },
      [mx, room.roomId],
    ),
  );
  const submitting = submitState.status === AsyncStatus.Loading;

  const handleSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
    evt.preventDefault();
    const target = evt.target as HTMLFormElement;
    const limitInput = target.elements.namedItem('limitInput') as HTMLInputElement | null;
    if (!limitInput) return;
    const parsed = parseInt(limitInput.value, 10);
    const value = Number.isNaN(parsed) || parsed < 0 ? 0 : parsed;
    submit(value);
  };

  return (
    <SequenceCard
      className={SequenceCardStyle}
      variant="SurfaceVariant"
      direction="Column"
      gap="400"
    >
      <SettingTile
        title="Voice Channel Limit"
        description="Set the maximum number of participants allowed in this room's voice call. Set to 0 for no limit. Enforced on the server for all Matrix clients."
      >
        <Box as="form" onSubmit={handleSubmit} gap="200" alignItems="Center">
          <Box style={{ maxWidth: '100px' }} grow="Yes">
            <Input
              key={maxUsers}
              name="limitInput"
              defaultValue={maxUsers}
              type="number"
              min={0}
              max={99}
              size="300"
              variant="Secondary"
              radii="300"
              readOnly={!canEdit}
              disabled={!canEdit}
            />
          </Box>
          <Button
            type="submit"
            size="300"
            variant="Primary"
            fill="Solid"
            radii="300"
            disabled={!canEdit || submitting}
            before={submitting ? <Spinner size="100" variant="Primary" fill="Solid" /> : undefined}
          >
            <Text size="B300">Save</Text>
          </Button>
        </Box>
        {submitState.status === AsyncStatus.Error && (
          <Text style={{ color: color.Critical.Main }} size="T200">
            {(submitState.error as MatrixError).message}
          </Text>
        )}
      </SettingTile>
    </SequenceCard>
  );
}
