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

interface LivekitConfigContent {
  service_url?: string;
}

/**
 * Room-specific LiveKit configuration component.
 * Allows room admins to override the LiveKit service URL for calls in this room.
 */
export function LivekitConfig() {
  const mx = useMatrixClient();
  const room = useRoom();
  const powerLevels = usePowerLevels(room);
  const creators = useRoomCreators(room);
  const permissions = useRoomPermissions(creators, powerLevels);

  const stateEvent = useStateEvent(room, StateEvent.RoomLivekitConfig);
  const currentConfig = stateEvent?.getContent<LivekitConfigContent>();
  const currentUrl = currentConfig?.service_url || '';

  const [urlValue, setUrlValue] = useState(currentUrl);
  const [urlError, setUrlError] = useState<string>();

  const [saveState, saveConfig] = useAsyncCallback(
    useCallback(
      async (serviceUrl: string) => {
        const content: LivekitConfigContent = serviceUrl
          ? { service_url: serviceUrl }
          : {};

        await mx.sendStateEvent(room.roomId, StateEvent.RoomLivekitConfig as any, content, '');
      },
      [mx, room]
    )
  );

  const canEdit = permissions.stateEvent(StateEvent.RoomLivekitConfig, mx.getUserId()!);

  const handleSave: FormEventHandler<HTMLFormElement> = async (evt) => {
    evt.preventDefault();
    const serviceUrl = urlValue.trim();

    // Basic URL validation
    if (serviceUrl && !serviceUrl.startsWith('http://') && !serviceUrl.startsWith('https://')) {
      setUrlError('URL must start with http:// or https://');
      return;
    }

    setUrlError(undefined);
    await saveConfig(serviceUrl);
  };

  const handleClear = async () => {
    setUrlValue('');
    setUrlError(undefined);
    await saveConfig('');
  };

  const hasChanges = urlValue !== currentUrl;
  const isSaving = saveState.status === AsyncStatus.Loading;

  return (
    <SequenceCard
      className={SequenceCardStyle}
      variant="SurfaceVariant"
      direction="Column"
      gap="400"
    >
      <SettingTile
        title="LiveKit Service URL"
        description="Override the LiveKit JWT service endpoint for Matrix RTC calls in this room. Leave empty to use the server default or user preference."
      />
      <Box as="form" onSubmit={handleSave} direction="Column" gap="200" style={{ padding: '0 16px' }}>
        <Input
          value={urlValue}
          onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
            setUrlValue(e.target.value);
            setUrlError(undefined);
          }}
          placeholder="https://example.com/livekit/jwt"
          size="300"
          variant="Secondary"
          radii="300"
          disabled={!canEdit || isSaving}
          style={{ width: '100%' }}
        />
        {urlError && (
          <Text size="T200" style={{ color: color.Critical.Main }}>
            {urlError}
          </Text>
        )}
        {saveState.status === AsyncStatus.Error && (
          <Text size="T200" style={{ color: color.Critical.Main }}>
            Failed to save: {saveState.error instanceof Error ? saveState.error.message : 'Unknown error'}
          </Text>
        )}
        {saveState.status === AsyncStatus.Success && !hasChanges && (
          <Text size="T200" style={{ color: color.Success.Main }}>
            Configuration saved
          </Text>
        )}
        <Box gap="200" alignItems="Center">
          <Button
            type="submit"
            size="300"
            variant="Primary"
            fill="Solid"
            radii="300"
            disabled={!canEdit || isSaving || !hasChanges}
            before={isSaving && <Spinner size="100" variant="Primary" fill="Solid" />}
          >
            <Text size="B300">Save</Text>
          </Button>
          {currentUrl && (
            <Button
              type="button"
              size="300"
              variant="Critical"
              fill="None"
              radii="300"
              disabled={!canEdit || isSaving}
              onClick={handleClear}
            >
              <Text size="B300">Clear</Text>
            </Button>
          )}
          {!canEdit && (
            <Text size="T200" priority="300">
              You don't have permission to change this setting
            </Text>
          )}
        </Box>
      </Box>
    </SequenceCard>
  );
}
