import React, { useState, useCallback, ChangeEventHandler } from 'react';
import {
  Box,
  Button,
  config,
  Dialog,
  Input,
  Text,
  Overlay,
  OverlayBackdrop,
  OverlayCenter,
} from 'folds';
import FocusTrap from 'focus-trap-react';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { useUserPresence } from '../../hooks/useUserPresence';
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';

/**
 * Props for the CustomStatusDialog component
 */
export interface CustomStatusDialogProps {
  /** Whether the dialog is currently open */
  open: boolean;
  /** Callback function invoked when the dialog should close */
  onClose: () => void;
}

/**
 * CustomStatusDialog Component
 * 
 * Provides a dialog interface for users to set or clear their custom status message.
 * The status is stored in Matrix presence and will be visible to other users.
 * 
 * @param props - Component props
 * @returns The custom status dialog component
 */
export function CustomStatusDialog({ open, onClose }: CustomStatusDialogProps) {
  const mx = useMatrixClient();
  const userId = mx.getUserId();
  const presence = useUserPresence(userId ?? '');
  
  const [statusText, setStatusText] = useState(presence?.status || '');
  
  /**
   * Handles input changes for the status text field
   * @param evt - The change event from the input
   */
  const handleChange: ChangeEventHandler<HTMLInputElement> = (evt) => {
    setStatusText(evt.currentTarget.value);
  };
  
  /**
   * Async callback to save the status to Matrix presence
   */
  const [saveState, saveStatus] = useAsyncCallback(
    useCallback(async () => {
      await mx.setPresence({
        presence: presence?.presence || 'online',
        status_msg: statusText,
      });
      onClose();
    }, [mx, presence?.presence, statusText, onClose])
  );
  
  /**
   * Async callback to clear the status from Matrix presence
   */
  const [clearState, clearStatus] = useAsyncCallback(
    useCallback(async () => {
      await mx.setPresence({
        presence: presence?.presence || 'online',
        status_msg: '',
      });
      setStatusText('');
      onClose();
    }, [mx, presence?.presence, onClose])
  );
  
  /**
   * Handles form submission to save the custom status
   * @param evt - The form submit event
   */
  const handleSubmit = (evt: React.FormEvent) => {
    evt.preventDefault();
    saveStatus();
  };
  
  /**
   * Handles the clear status button click
   */
  const handleClear = () => {
    clearStatus();
  };

  if (!open) return null;

  return (
    <Overlay open backdrop={<OverlayBackdrop />}>
      <OverlayCenter>
        <FocusTrap
          focusTrapOptions={{
            initialFocus: false,
            onDeactivate: onClose,
            clickOutsideDeactivates: true,
          }}
        >
          <Dialog>
            <Box
              as="form"
              onSubmit={handleSubmit}
              direction="Column"
              gap="400"
              style={{ padding: config.space.S400 }}
            >
              <Box direction="Column" gap="100">
                <Text size="H4">Set Custom Status</Text>
                <Text size="T300" priority="400">
                  Your custom status will be visible to other users
                </Text>
              </Box>
              
              <Box direction="Column" gap="200">
                <Input
                  value={statusText}
                  onChange={handleChange}
                  placeholder="What's on your mind?"
                  maxLength={100}
                  autoFocus
                  disabled={saveState.status === AsyncStatus.Loading || clearState.status === AsyncStatus.Loading}
                />
                {statusText.length > 0 && (
                  <Text size="T200" priority="300">
                    {statusText.length}/100 characters
                  </Text>
                )}
              </Box>

              {(saveState.status === AsyncStatus.Error || clearState.status === AsyncStatus.Error) && (
                <Text size="T300" priority="400" style={{ color: 'var(--color-critical-main)' }}>
                  Failed to update status. Please try again.
                </Text>
              )}

              <Box direction="Row" gap="200" justifyContent="End">
                <Button
                  type="button"
                  variant="Secondary"
                  onClick={onClose}
                  disabled={saveState.status === AsyncStatus.Loading || clearState.status === AsyncStatus.Loading}
                >
                  <Text size="B400">Cancel</Text>
                </Button>
                {presence?.status && (
                  <Button
                    type="button"
                    variant="Critical"
                    fill="None"
                    onClick={handleClear}
                    disabled={saveState.status === AsyncStatus.Loading || clearState.status === AsyncStatus.Loading}
                  >
                    <Text size="B400">Clear Status</Text>
                  </Button>
                )}
                <Button
                  type="submit"
                  variant="Primary"
                  disabled={saveState.status === AsyncStatus.Loading || clearState.status === AsyncStatus.Loading}
                >
                  <Text size="B400">
                    {saveState.status === AsyncStatus.Loading ? 'Saving...' : 'Save'}
                  </Text>
                </Button>
              </Box>
            </Box>
          </Dialog>
        </FocusTrap>
      </OverlayCenter>
    </Overlay>
  );
}
